newbie question: Please help me stop creating constructors

2010-02-15 Thread Yaron
I am writing a calculator to figure out if I should sell or rent my
home using Clojure. This is my first Clojure program so I'm about as
wet behind the ears as it gets. So far everything is actually going
really well (reminds me of the fun I had with Scheme in college) but
for one thing. My calculator needs 30+ arguments from the user in
order to run. Furthermore I have a bunch of secondary values that are
derived from the arguments the user submits.

So imagine the user submits a value A. I will have a value B whose
definition will be something like (+ 1 A) (yes, more complex in
reality, but you get the idea).

If I were back in Java or C# I would define a class, submit A (and
it's 29+ friends) in the constructor and then create a property on the
class B.

In Clojure I have taken a different approach. I first create (def *A*
3) where 3 is a completely bogus value I just made up. Then at run
time I use bindings to re-bind A to the actual value the user passed
in.

But my problem is, what to do about B? I thought of doing something
like (def *B* 3) and then in the binding passing in a function like
(defn B-Gen [] (+ *A* 1)) to create a new binding to B but I quickly
realized this would be a bug inducing nightmare. If I forget to
include one of the derived values in the binding or put them in the
wrong order then I would get the wrong value.

So what I currently do is:
(def *A* 3) ; A bogus value that will later be rebound
(defn B [] (+ *A* 3))

The good news is, that this works and doesn't require any book
keeping.

The bad news is that it's ugly. If I want to do something trivial like
divide B by 2 I have to call B as a function(/ (B) 2) instead of the
more natural (/ B 2). And of course this approach is pretty
unfortunate from a performance perspective as I'm constantly having to
recalculate what are effectively static values. Yes, I could use
memoization but many of these values are pretty trivial (usually just
algebra equations) and I suspect the overhead of memoization exceeds
the perf improvement.

But in any case the whole approach of having to take what really are
static values and turn them into functions feels really hacky. So my
guess is that I'm thinking about this problem the wrong way. I'm stuck
in my old imperative/OO constructor world.

What's the right way to think about primary values that will be
rebound (once) that then have dependent values that need to be
recalculated when that rebinding happens?

  Thanks,

  Yaron

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


Re: newbie question: Please help me stop creating constructors

2010-02-16 Thread Yaron
Sean and Richard perhaps I can address both of your mails in a single
go. Here is an example of one of the functions from my calculator:

(defn tax_deductible_expenses
"The total expenses incurred in business month m that are deductible
from federal income tax"
[m]
(let
[prepHouse (inflate *Prep_House_0* m)
 fixedMonthlyCost (if (= m (months_in_business)) 0
(fixed_monthly_cost m))]
(condp = (house_state m)
:ForLease (+ fixedMonthlyCost (if (= 
(month_in_rental_cycle m) 0)
prepHouse 0))
:Leased (+ fixedMonthlyCost (* (rental_income m) (+
*Management_Fee* (if (= (month_in_rental_cycle m)
*Months_To_Find_Tenant*) *Tenant_Finding_Fee* 0
:ForSale (+ fixedMonthlyCost (if (= m 
(months_actively_renting))
prepHouse 0))
:Sold (house_sales_expenses m

Right now the function takes a single argument, m which is the month
that tax deductible expenses are being calculated for. All the other
values it needs are "constants" (e.g. either values provided at the
start by the user or derived values).

Now please look at a test I wrote to make sure the function does what
I think it does:

(deftest tax_deductible_expenses_basic
  (binding
[*Months_To_Find_Tenant* 5
 *Months_In_Lease* 5
 *Lease_Cycles* 1
 *House_Sales_Price_0* 300
 *Monthly_Inflation_Rate* 0.002
 *Buying_Agent_Fee_Type* :Percentage
 *Buying_Agent_Fee_Number* 0.05
 *Selling_Agent_Fee_Type* :FlatFee
 *Selling_Agent_Fee_Number* 1000
 *Other_Sales_Fee_0* 100
 *Excise_Tax* 0.5
 *Original_Loan_Amount* 1
 *Monthly_Loan_Interest* (/ 0.05 12)
 *Months_In_Loan* (* 10 12)
 *Loan_Month_At_Start* 3
 *Prep_House_0* 100
 *Management_Fee* 2
 *Tenant_Finding_Fee* 0.5
 *Months_To_Sell* 3]
 (is (= (tax_deductible_expenses 0) (+ (fixed_monthly_cost 0)
100)))
 (is (= (tax_deductible_expenses 1) (fixed_monthly_cost 1)))
 (is (= (tax_deductible_expenses 5) (+ (fixed_monthly_cost 5) (*
(rental_income 5) 2.5
 (is (= (tax_deductible_expenses 7) (+ (fixed_monthly_cost 7) (*
(rental_income 7) 2
 (is (= (tax_deductible_expenses 10) (+ (fixed_monthly_cost 10)
(inflate 100 10
 (is (= (tax_deductible_expenses 12) (fixed_monthly_cost 12)))
 (is (= (tax_deductible_expenses 13) (house_sales_expenses 13)

For the method tax_deductible_expenses to run it ends up requiring 19
user defined values. That's a whole lot of arguments to pass into a
function. Obviously I could wrap them up in a StructMap but then I get
expressions like (+ 1 (args :B)) which doesn't seem much better than
(+1 (B)).

The issue I'm really trying to put my finger on is - these arguments
really and truly are 'constants' within the context of the calculator.
But they are constants whose values are not known as compile time but
rather are known at run time. Does Clojure have a way to express a
'late bound' constant or is the 'right' solution to pass around 19+
arguments to functions or passing around StructMaps or making
everything into thunks?

   Thanks!

 Yaron

On Feb 15, 1:33 pm, Richard Newman  wrote:
> > So imagine the user submits a value A. I will have a value B whose
> > definition will be something like (+ 1 A) (yes, more complex in
> > reality, but you get the idea).
>
> In Java, everything's an object, so you go about this by defining some  
> class. All of its private members, its constructors, and its accessors  
> are there to support one thing: should I sell or rent my home?
>
> That is, rather than saying something like:
>
> should-i-sell given that:
>    current-home-price = 100,000
>    current-interest-rate = 5.2%
>    ...
>
> you say
>
> HomeCalculator c = new HomeCalculator(10, 5.2, ...);
> boolean shouldSell = c.shouldSell();
>
> and the logic is tied up in the shouldSell method definition.
>
> When someone calls .setA(...), you have to recompute B, or you have to  
> make sure that B is dynamically computed in .getB().
>
> That's not how you do things in a functional programming language. You  
> don't define global variables "B" and "A". Define functions that  
> compute things; thread them together; and then push your values in the  
> top.
>
> Start from the bottom up and the top down together; build a tree of  
> functions that compute what you want. For example, you might think  
> "ah, I need to figure out my monthly payment on my mortgage". That's a  
> function of the initial principal, the term, and the rate:
>
> (defn monthly-payment [principal term-in-months interest-rate]
>    ...)
>
> Then you want to figure out how much more or less you'll 

Re: newbie question: Please help me stop creating constructors

2010-02-16 Thread Yaron
I have posted a file (http://www.goland.org/sellorrent.pdf) which
explains the math behind the calculator. The file gives all the
algebra needed to implement the calculator. At the moment I'm just
taking the boneheaded approach and implementing all the logic in
Clojure as more or less a one to one mapping of the functions in the
PDF file.

Please, please, please, keep in mind that the linked article is a very
rough, rough draft. It is not ready for prime time. I am only sharing
it so that you can see what I'm trying to implement and hopefully
guide me to the right way to implement it.

It seems however that the consensus of the group based on what I've
said so far is to pass around state in a structmap. This is nice in
that it makes each function completely self contained (e.g. no
external references). It's unfortunate in that it now means that every
single function needs this extra argument and every variable access
either needs to use the :keys feature in the arguments or has to
directly refer to the keys in the map.

I really wish there was a way for me to just declare a context, define
a bunch of statics and then define all my methods inside of that
context. But it doesn't seem like this is the clojure way of handling
the problem. Where as many aspects of functional programming make a
ton of sense to me having to carry a map around everywhere doesn't
seem like an advantage. But I'm probably just missing something.

   Yaron


On Feb 16, 1:20 pm, Richard Newman  wrote:
> > For the method tax_deductible_expenses to run it ends up requiring 19
> > user defined values. That's a whole lot of arguments to pass into a
> > function. Obviously I could wrap them up in a StructMap but then I get
> > expressions like (+ 1 (args :B)) which doesn't seem much better than
> > (+1 (B)).
>
> Pass them in as a map, and destructure at the start of the function:
>
>    (defn tax-deductible-expenses [{:keys [management-fee
>                                           tenant-finding-fee ...]}]
>      ...)
>
> > The issue I'm really trying to put my finger on is - these arguments
> > really and truly are 'constants' within the context of the calculator.
> > But they are constants whose values are not known as compile time but
> > rather are known at run time.
>
> That they're "constant" does not mean that you shouldn't pass them as  
> arguments to your functions.
>
> Most values obtained from users or config files are such "run-time  
> constants". Heck, many values in most programs are -- "HTTP listener  
> port", "log file location", etc.
>
> You still invoke your HTTP server with a :port argument.
>
> Indeed, the more fixed values you have, the less likely it is that you  
> should define a var for each. Maybe one var containing a map, but I'd  
> still pass the map around rather than having each function implicitly  
> refer to it. It makes testing easier.
>
> > Does Clojure have a way to express a
> > 'late bound' constant or is the 'right' solution to pass around 19+
> > arguments to functions or passing around StructMaps or making
> > everything into thunks?
>
> The reason you pass them around as arguments is so that the behavior  
> of your functions is precisely determined *only* by its arguments --  
> they are pure.
>
> That means that you can memoize them, easily write tests for them,  
> have them work correctly when part of a lazy sequence (which will  
> often be evaluated outside the scope of your bindings), etc.
>
> For example: how would you compare the tax-deductible-expenses of two  
> clients? You'd need to invoke the function twice, with a huge nest of  
> bindings around each call. Much better would be to store the  
> appropriate values in two maps, then say
>
>    (< (tax-deductible-expenses 0 john-data)
>       (tax-deductible-expenses 0 bill-data))
>
> -R

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
I did but it requires two levels of macro and that made me nervous.
The problem is derived values. When defining a binding, near as I can
tell, the values in the binding cannot see other values in the
binding. In other words:

(def *A* 10)
(binding [*A* 3 B (+ foo 1)] B)

Returns 11, not 4.

So to use the macro I have to:

(def *A* bogus_value)
(def B bogus_value)

(defmacro in-environment [env & body]
  `(binding [*A* :A ..]
(binding [B (+ *A* 1)...]
 ~...@body))

I think this would actually work. But it requires a bunch of
accounting (all the bogus global defs) and introduces some worrisome
ordering issues. For example, let's say I have a value C whose
definition is (def C (+ B 1)). I can't define it using the previous
macro. Because, again, bindings can't see each other. So now I'd have
to write a macro that dynamically created a whole set of nested
bindings. Which seems like a lot of work.

In other words:

(binding [*A* :A...]
  (binding [B (+ *A* 1)...]
   (binding [C (+ *B* 1)...]
 etc.

And I can't use let (which does allow for internal visibility) because
then other functions I call will bind to the global value not the let
value.

   Yaron

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
I actually started off doing exactly what you suggested. The original
version of my program used a map for the arguments and then used
explicit arguments when the number of arguments fell to a reasonable
level.

For example, I started off with:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[Months_To_Find_Tenant Months_In_Lease Lease_Cycles Months_To_Sell]
(-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
Months_To_Sell)))

Which got called as (months_in_business Months_To_Find_Tenant
Months_In_Lease Lease_Cycles Months_To_Sell)

But this was a lot of typing every time I wanted to call the function.
So I changed it to:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[:keys [Months_To_Find_Tenant Months_In_Lease Lease_Cycles
Months_To_Sell]]
(-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
Months_To_Sell)))

Which got called as (months_in_business bag_o_args)

This at least meant less typing when calling the function but defining
the function still required a bunch of typing.

So eventually I just went to:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[]
(-> (+ *Months_To_Find_Tenant* *Months_In_Lease*) (* *Lease_Cycles*)
(+ *Months_To_Sell*)))

Which was called as: (months_in_business)

At least there wasn't much typing involved but now I had a bunch of
thunks running around. Which is what brought me to the group in the
first place.

It seems to me that there is a design principal here somewhere that
says something like "One shouldn't have to pass static values around
as arguments to functions". But because there is nothing like an
object context in Clojure this ended up meaning that derived values
like months_in_business have to be thunks. Which I though was
inelegant.

If, on the other hand, I was implementing this in an object oriented
language I would just say:

class foo
 var A
 var B
  foo (bag_o_args)
 {
A = (bag_o_args A)
B = A+1
 }

And I would be done. No heaps of typing. No thunks. Just what looks to
me like a nice simple solution.

But I recognize that I'm just running home to mommy because my
background is OO. That's why I came to the group in the first place.
Since I know I'm blinded by my OO past I wanted to see if there was an
approach to the problem in Clojure that was as easy and straight
forward as what I would have done in an OO language.

That having been said, defining a bunch of thunks isn't the worst
thing in the world. But it is unfortunate from both a design and
performance perspective.

Yaron

On Feb 16, 11:07 pm, Richard Newman  wrote:
> > It seems however that the consensus of the group based on what I've
> > said so far is to pass around state in a structmap.
>
> Not necessarily a struct-map. Just a map.
>
> > This is nice in
> > that it makes each function completely self contained (e.g. no
> > external references). It's unfortunate in that it now means that every
> > single function needs this extra argument and every variable access
> > either needs to use the :keys feature in the arguments or has to
> > directly refer to the keys in the map.
>
> Not necessarily. At some point your functions should be fine-grained  
> enough that they only take a couple of arguments. As soon as you drop  
> below 6 or 7, where they're all mandatory, switch to ordinary function  
> argument style.
>
> Wherever you call those functions should do the unpacking.
>
> E.g.,
>
> (defn outer-1 [{:keys [foo bar baz noo]}]
>    (let [interm (foo-bar foo bar)
>          fiddle (frostrup baz noo)]
>      (tweep interm fiddle)))
>
> After all, your house-sale-profit function should be expressed in  
> terms of two arguments:
>
> (defn house-sale-profit [house-sale-price house-sale-expenses]
>    ...)
>
> It doesn't care about the other 17.
>
> Another thing: that big entry point function is like a much tidier  
> version of the Java constructor that you created with 19 arguments --  
> tidier in that you can use named keys or a map to identify the  
> arguments.

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
I actually started off doing exactly what you suggested. The original
version of my program used a map for the arguments and then used
explicit arguments when the number of arguments fell to a reasonable
level.

For example, I started off with:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[Months_To_Find_Tenant Months_In_Lease Lease_Cycles Months_To_Sell]
(-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
Months_To_Sell)))

Which got called as (months_in_business Months_To_Find_Tenant
Months_In_Lease Lease_Cycles Months_To_Sell)

But this was a lot of typing every time I wanted to call the function.
So I changed it to:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[:keys [Months_To_Find_Tenant Months_In_Lease Lease_Cycles
Months_To_Sell]]
(-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
Months_To_Sell)))

Which got called as (months_in_business bag_o_args)

This at least meant less typing when calling the function but defining
the function still required a bunch of typing.

So eventually I just went to:

(defn months_in_business
"The total number of months we will be in the business of renting out
our home"
[]
(-> (+ *Months_To_Find_Tenant* *Months_In_Lease*) (* *Lease_Cycles*)
(+ *Months_To_Sell*)))

Which was called as: (months_in_business)

At least there wasn't much typing involved but now I had a bunch of
thunks running around. Which is what brought me to the group in the
first place.

It seems to me that there is a design principal here somewhere that
says something like "One shouldn't have to pass static values around
as arguments to functions". But because there is nothing like an
object context in Clojure this ended up meaning that derived values
like months_in_business have to be thunks. Which I though was
inelegant.

If, on the other hand, I was implementing this in an object oriented
language I would just say:

class foo
 var A
 var B
  foo (bag_o_args)
 {
A = (bag_o_args A)
B = A+1
 }

And I would be done. No heaps of typing. No thunks. Just what looks to
me like a nice simple solution.

But I recognize that I'm just running home to mommy because my
background is OO. That's why I came to the group in the first place.
Since I know I'm blinded by my OO past I wanted to see if there was an
approach to the problem in Clojure that was as easy and straight
forward as what I would have done in an OO language.

That having been said, defining a bunch of thunks isn't the worst
thing in the world. But it is unfortunate from both a design and
performance perspective.

Yaron

On Feb 16, 11:07 pm, Richard Newman  wrote:
> > It seems however that the consensus of the group based on what I've
> > said so far is to pass around state in a structmap.
>
> Not necessarily a struct-map. Just a map.
>
> > This is nice in
> > that it makes each function completely self contained (e.g. no
> > external references). It's unfortunate in that it now means that every
> > single function needs this extra argument and every variable access
> > either needs to use the :keys feature in the arguments or has to
> > directly refer to the keys in the map.
>
> Not necessarily. At some point your functions should be fine-grained  
> enough that they only take a couple of arguments. As soon as you drop  
> below 6 or 7, where they're all mandatory, switch to ordinary function  
> argument style.
>
> Wherever you call those functions should do the unpacking.
>
> E.g.,
>
> (defn outer-1 [{:keys [foo bar baz noo]}]
>    (let [interm (foo-bar foo bar)
>          fiddle (frostrup baz noo)]
>      (tweep interm fiddle)))
>
> After all, your house-sale-profit function should be expressed in  
> terms of two arguments:
>
> (defn house-sale-profit [house-sale-price house-sale-expenses]
>    ...)
>
> It doesn't care about the other 17.
>
> Another thing: that big entry point function is like a much tidier  
> version of the Java constructor that you created with 19 arguments --  
> tidier in that you can use named keys or a map to identify the  
> arguments.

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
I think I see what you're saying. But honestly my goal isn't to
replicate the OO experience. My goal is to replicate how easy OO made
this specific scenario. In other words I want to use Clojure properly
and trying to paste an OO framework on Clojure has got to be a major
anti-pattern. I'm just trying to figure out what the right pattern is
because the fact that I'm forced to make the derived values into
thunks feels really wrong but I honestly don't know what's right in
the context of Clojure.

On Feb 17, 10:39 am, CuppoJava  wrote:
> HiYaron,
>
> You've slightly misunderstood my suggestion. I hope this will shed
> some reasoning on it:
>
> In OO, what you are effectively doing is this:
>
> The Object represents the "environment" under which you do your
> calculations.
> The "environment" object is created by your constructor.
> Once this "environment" has been created, you can use it to do
> calculations using "foo.tax_deductible_expenses(1)".
>
> My example is meant to capture this style of programming. (Whether
> this style is appropriate is up to you to decide.)
>
> The "environment" is represented by a map.
> You can write a function that creates an "environment" just like how
> you can write a constructor to create an environment object in Java.
>   eg.  new-environment( ... )
> Once this environment has been created, you may use it to do
> calculations using
>   "(in-environment foo
>      (tax-deductible-expenses 1))"
>
> The in-environment macro is not meant to contain any logic. It is
> solely meant to save you some typing.
>
> Hope that's more clear.
>   -Patrick

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
The reason for typing so much is maintainability. I'll have to come
back to this code again and again over a period of years and there's
no chance in heck I'll remember anything I did before. So I've learned
that using clearer variable names, even with a little extra typing, is
a price worth paying.

On Feb 17, 10:46 am, David Nolen  wrote:
> (defn months_in_business
>        "The total number of months we will be in the business of renting out
> our home"
>        [:keys [Months_To_Find_Tenant Months_In_Lease Lease_Cycles
> Months_To_Sell]]
>        (-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
> Months_To_Sell)))
>
> ->
>
> I have no idea why you want to type this much:
>
> (defn months-in-business
>   [:keys [mtft mil lc mts]
>   (-> (+ mtft mil) (* lc) (+ mts))
>
> But how do we know what these abbreviations mean while we develop our
> application? Write a couple of helper functions:
>
> (defn map-to-humane-repr [m]
>      (let [ok (keys m)
>            vs (vals m)]
>        (zipmap (map mappings ok) vs)))
>
> (def *dummy*
>      {:mtft 1,
>       :mil 24,
>       :lc 5,
>       :mts 12})
>
> (map-to-humane-repr *dummy*) ->
>
> {"Months to Sell" 12,
>  "Lease Cycles" 5,
>  "Months In Lease" 24,
>  "Months To Find Tenant" 1}

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
That's actually quite a nifty use of the fact that code/data is the
same in Clojure. But how do I test things out? In other words, how do
I make sure that the expression defining a# is correct? Especially
when any test has to itself be in the context of all the variables?

But more to the point I think there is a difference between possible
and desirable. You're giving me what I asked for, e.g. a way to
achieve my goal of not having the derived values be thunks. But I
can't help but think that I'm just approaching the whole problem in
the wrong way in Clojure. That's why I posted 
http://www.goland.org/sellorrent.pdf.

I don't expect anyone to actually read, rather I was hoping some folks
who know Clojure might just glance at it to get the rhythm of the
math. It's the pattern, not the detail that matters. How should what
is essentially a monster algebra equation be codified in Clojure?

On Feb 17, 10:48 am, Tom Faulhaber  wrote:
> You can combine let and binding like this to make this slightly more
> elegant:
>
> (let [a# 'expr involving *A* *B* and *C*''
>       b# 'expr involving *A* *B* and *C*''
>       c# 'expr involving *A* *B* and *C*'']
>   (binding [*A* a#
>                *B* b#
>                *C* c#]
>      ...))
>
> Note the x# form which does an implicit gensym for you so you get
> unique names.
>
> This at least reduces it from n levels to two levels. It would be
> pretty easy to build a parallel-binding macro that did this for you.
>
> hth,
>
> Tom
>
> On Feb 17, 10:09 am,Yaron wrote:
>
> > I did but it requires two levels of macro and that made me nervous.
> > The problem is derived values. When defining a binding, near as I can
> > tell, the values in the binding cannot see other values in the
> > binding. In other words:
>
> > (def *A* 10)
> > (binding [*A* 3 B (+ foo 1)] B)
>
> > Returns 11, not 4.
>
> > So to use the macro I have to:
>
> > (def *A* bogus_value)
> > (def B bogus_value)
>
> > (defmacro in-environment [env & body]
> >   `(binding [*A* :A ..]
> >     (binding [B (+ *A* 1)...]
> >     �...@body))
>
> > I think this would actually work. But it requires a bunch of
> > accounting (all the bogus global defs) and introduces some worrisome
> > ordering issues. For example, let's say I have a value C whose
> > definition is (def C (+ B 1)). I can't define it using the previous
> > macro. Because, again, bindings can't see each other. So now I'd have
> > to write a macro that dynamically created a whole set of nested
> > bindings. Which seems like a lot of work.
>
> > In other words:
>
> > (binding [*A* :A...]
> >   (binding [B (+ *A* 1)...]
> >    (binding [C (+ *B* 1)...]
> >      etc.
>
> > And I can't use let (which does allow for internal visibility) because
> > then other functions I call will bind to the global value not the let
> > value.
>
> >    Yaron

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


Re: newbie question: Please help me stop creating constructors

2010-02-17 Thread Yaron
Absolutely. I typed up an example in Scala.

class RentOrSell(val Months_To_Find_Tenant: Int, val Months_In_Lease:
Int, val Lease_Cycles: Int, val Months_To_Sell: Int) {
  val months_in_business: Int = ((Months_To_Find_Tenant +
Months_In_Lease) * Lease_Cycles) + Months_To_Sell
}

When I create a class instance I pass in the user defined variables (I
only used 4 in this example). Those values are then bound as invariant
values and used to create months_in_business which is itself an
invariant value (e.g. bound at class creation time and then
immutable).

This is the effect I was expecting. That I could define both the user
supplied values and the derived values as immutable values. Instead I
had to create thunks for the derived values for the reasons previously
described.

But again I'm completely open to the idea that I'm just going about
this all wrong. I have spent more years of my life than I care to
remember writing OO code so I have no doubt I'm relying on instincts
that just don't apply here.

Ideally I'd love to figure out how to properly write a program that
implements http://www.goland.org/sellorrent.pdf in Clojure rather than
beat Clojure into looking like what I'm used to from my OO days. Put
another way, I speak Clojure with a really thick OO accent and I'd
like to learn better how to speak it like a native. :)

   Yaron

On Feb 17, 11:53 am, Laurent PETIT  wrote:
> Hello,
>
> 2010/2/17Yaron:
>
>
>
> > I actually started off doing exactly what you suggested. The original
> > version of my program used a map for the arguments and then used
> > explicit arguments when the number of arguments fell to a reasonable
> > level.
>
> > For example, I started off with:
>
> > (defn months_in_business
> >        "The total number of months we will be in the business of renting out
> > our home"
> >        [Months_To_Find_Tenant Months_In_Lease Lease_Cycles Months_To_Sell]
> >        (-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
> > Months_To_Sell)))
>
> > Which got called as (months_in_business Months_To_Find_Tenant
> > Months_In_Lease Lease_Cycles Months_To_Sell)
>
> > But this was a lot of typing every time I wanted to call the function.
> > So I changed it to:
>
> > (defn months_in_business
> >        "The total number of months we will be in the business of renting out
> > our home"
> >        [:keys [Months_To_Find_Tenant Months_In_Lease Lease_Cycles
> > Months_To_Sell]]
> >        (-> (+ Months_To_Find_Tenant Months_In_Lease) (* Lease_Cycles) (+
> > Months_To_Sell)))
>
> > Which got called as (months_in_business bag_o_args)
>
> > This at least meant less typing when calling the function but defining
> > the function still required a bunch of typing.
>
> > So eventually I just went to:
>
> > (defn months_in_business
> >        "The total number of months we will be in the business of renting out
> > our home"
> >        []
> >        (-> (+ *Months_To_Find_Tenant* *Months_In_Lease*) (* *Lease_Cycles*)
> > (+ *Months_To_Sell*)))
>
> > Which was called as: (months_in_business)
>
> > At least there wasn't much typing involved but now I had a bunch of
> > thunks running around. Which is what brought me to the group in the
> > first place.
>
> > It seems to me that there is a design principal here somewhere that
> > says something like "One shouldn't have to pass static values around
> > as arguments to functions". But because there is nothing like an
> > object context in Clojure this ended up meaning that derived values
> > like months_in_business have to be thunks. Which I though was
> > inelegant.
>
> > If, on the other hand, I was implementing this in an object oriented
> > language I would just say:
>
> > class foo
> >  var A
> >  var B
> >  foo (bag_o_args)
> >  {
> >    A = (bag_o_args A)
> >    B = A+1
> >  }
>
> I would like to try to help, but I first need to understand your
> (pseudo?) OO langage above.
> Could you detail it a little bit more ?
>
>
>
> > And I would be done. No heaps of typing. No thunks. Just what looks to
> > me like a nice simple solution.
>
> > But I recognize that I'm just running home to mommy because my
> > background is OO. That's why I came to the group in the first place.
> > Since I know I'm blinded by my OO past I wanted to see if there was an
> > approach to the problem in Clojure that was as easy and straight
> > forward as what I would have done in an OO language.
>
> > That having been said,

Re: newbie question: Please help me stop creating constructors

2010-02-18 Thread Yaron
Way back when I was a wee lad I had been taught that a thunk is any
function that takes no arguments. My definition for my derived values
never took any arguments because they exclusively relied on global
variables.

For example:

(defn months_actively_renting
"The number of months during the time we are in the rental business
that we are either trying to rent the house out or have rented it out"
[]
(* (+ *Months_To_Find_Tenant* *Months_In_Lease*) *Lease_Cycles*))

That's all I meant by the term thunk.

On Feb 17, 10:20 pm, Richard Newman  wrote:
> > I'm just trying to figure out what the right pattern is
> > because the fact that I'm forced to make the derived values into
> > thunks feels really wrong but I honestly don't know what's right in
> > the context of Clojure.
>
> I don't think you're using the term "thunk" correctly.
>
> A thunk is (usually) a no-argument function, typically used for things  
> like delayed evaluation, and typically capturing some environment. E.g.,
>
> (defn hello [thunk]
>    (println "Hello, " (thunk)))
>
> (defn make-name-thunk [name]
>    (fn [] name))
>
> (let [n (make-name-thunk "Jim")]
>    (println "Calling hello...")
>    (hello n))
>
> You are not making your derived values into thunks by this definition.  
> Your derived values are just that: values, computed by functions.  
> Compute them when you need them by invoking the appropriate functions  
> with the appropriate arguments.
>
> Can you explain what you mean by "thunk"?

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


Re: newbie question: Please help me stop creating constructors

2010-02-18 Thread Yaron
I spent a bunch of time reading and re-reading your mails.

Michal Marczyk's mail (which I read every line of, thank you for
taking the time to write it) was the one that made me get what
Richard Newman has with utmost patience (THANK YOU!), I believe,
been trying to gently beat into my head from the start.

Richard, your mails were extremely clear (and at this point I've read
them all at least 2 or 3 times) but my head was so far away from the
problem space that I needed a sufficient amount of beating before I
could finally even begin to grok anything. It took me forever to get
over the idea that I needed global variables. It was a stupid idee
fixe on my part.

I just took a piece of my code and re-worked it and made it available
at http://www.goland.org/rent_or_sell_refactor.clj.

My approach is as follows:

#1 - I removed all globally scoped defs (well, I left one, but it's
Months-In-Year and is just there for readability purposes). And per
Jarkko Oranen's mail I fixed the dashes. :)

#2 - I created a function called derived-args. It takes as input a map
that is to contain all the arguments provided by the user. It then
adds to that map all the derived values. This means that the derived
values get calculated exactly one time. It is the output of derived-
args that will be put at the very top of the function chain and passed
on down.

#3 - For some functions I explicitly just list out the arguments they
need. But I made a conscious decision not to do that in all cases. I
have a number of functions that I call a lot and constantly having to
break out their arguments when I call them would quickly grow tedious.
So instead I pass those functions the args map and then let them use
keys to break out the values. Probably the most egregious example of
this pattern is valid-month? I use this in preconditions all over the
place. So rather than passing its second argument, months-in-business,
as a separate argument I just pass in the whole args map and break out
the value inside of valid-month? The benefit of this approach is that
all the functions that call valid-month don't themselves have to break
out months-in-business in their keys, they can just pass in args.

Does http://www.goland.org/rent_or_sell_refactor.clj work more or less
the way y'all have been suggesting? In other words have I finally
created something that is heading in the 'right' direction? I realize
you can't properly judge it until I'm done but I wanted to find out if
I was roughly heading in the right direction.

   Thanks

 Yaron

On Feb 17, 10:36 pm, Richard Newman  wrote:
> > I don't expect anyone to actually read, rather I was hoping some folks
> > who know Clojure might just glance at it to get the rhythm of the
> > math. It's the pattern, not the detail that matters. How should what
> > is essentially a monster algebra equation be codified in Clojure?
>
> I looked at your PDF.
>
> You express the equations as functions. Turning your equation notation  
> into function notation -- I'll use Haskell's as an example:
>
> OpportunityCost = Rent - Sell
>
> becomes
>
> opportunityCost r s = r - s
>
> or in Clojure:
>
> (defn opportunity-cost [r s]
>(- r s))
>
> Note that the implicit arguments in your equational notation become  
> explicit arguments in the functional version.
>
> How do I compute r and s? Why, with functions of course! Let's take  
> Sell as an example.
>
> Sell = HouseSaleProfit0(1 +  
> RealMonthlyOpportunityCost)^MonthsInBusiness
>
> which becomes
>
> (defn sell [hsp-zero rmoc mib]
>(* hsp-zero
>   (exp (+ 1 rmoc) mib))); Assuming exp defined.
>
> Now, assuming that we have Rent, HSP0, RMOC, and MIB calculated (which  
> follows the same pattern), we compute our OpportunityCost:
>
> (defn -main []
>   ;; TODO: extract user arguments.
>   ;; ...
>   (let [hsp-zero (...)   ; More calculation.
>  rmoc (...)
> mib (...)]
> (println "Opportunity Cost: "
>   (opportunity-cost rent (sell hsp-zero rmoc mib
>
> To turn this into your final code, you need only:
>
> * Keep walking through your formulae until you've expressed everything  
> as functions;
> * Grab the nineteen or so "leaf" values you need from the user, and  
> plug them into your calls.
>
> When you have intermediate values, bind them with let, as I show above.
>
> Note that:
>
> * Each of the functions stands alone, defined in terms of its  
> arguments, and follows naturally from your equations
> * You can compute any intermediate stage, and print them out, log  
> 

Re: newbie question: Please help me stop creating constructors

2010-02-19 Thread Yaron
With this approach how would I test the individual functions defined
inside of the let? Wouldn't they be invisible to me and the test
framework which would only see "sell-or-rent"?

On Feb 18, 4:27 pm, John Williams  wrote:
> I'm no Clojure guru myself, but one approach you may want to consider is
> nest all your auxiliary functions inside the main function, and use ordinary
> let-bindings the same way you've been trying to use global bindings:
>
> (defn sell-or-rent [{:keys [supplied-1 supplied-2]}]
>   (let [derived-1 (+ 1 supplied-1)
>         derived-2 (* 2 supplied-2)]
>     (letfn [(f [x y z] ...)
>             (g [x] ...)]
>       ...)))
>
> This has the disadvantage of indenting all your helper functions much more
> than they would be otherwise, but it gets the job done without any messy
> global variables or thunks.  If you want to expose more functions than just
> sell-or-rent, you could write some very OO-flavored code:
>
> ;; Define a function to create objects.
> (defn pseudo-constructor [{:keys [supplied-1 supplied-2]}]
>   (let [member-var-1 (+ 1 supplied-1)
>         member-var-2 (* 2 supplied-2)]
>     (letfn [(private-method-1 [] "priv1")
>             (private-method-2 [] "priv2")]
>       {:public-method-1 (fn [x y z] "pub1")
>        :public-method-2 (fn [x y] "pub2")})))
>
> ;; Use the object.
> (let [obj (pseudo-constructor {:supplied-1 1
>                                :supplied-2 2})]
>   (println ((:public-method-1 obj) "x" "y" "z"))
>   (println ((:public-method-2 obj) "x" "y")))
>
> --jw
>
> On Mon, Feb 15, 2010 at 11:24 AM, Yaron  wrote:
> > I am writing a calculator to figure out if I should sell or rent my
> > home using Clojure. This is my first Clojure program so I'm about as
> > wet behind the ears as it gets. So far everything is actually going
> > really well (reminds me of the fun I had with Scheme in college) but
> > for one thing. My calculator needs 30+ arguments from the user in
> > order to run. Furthermore I have a bunch of secondary values that are
> > derived from the arguments the user submits.
>
> > So imagine the user submits a value A. I will have a value B whose
> > definition will be something like (+ 1 A) (yes, more complex in
> > reality, but you get the idea).
>
> > If I were back in Java or C# I would define a class, submit A (and
> > it's 29+ friends) in the constructor and then create a property on the
> > class B.
>
> > In Clojure I have taken a different approach. I first create (def *A*
> > 3) where 3 is a completely bogus value I just made up. Then at run
> > time I use bindings to re-bind A to the actual value the user passed
> > in.
>
> > But my problem is, what to do about B? I thought of doing something
> > like (def *B* 3) and then in the binding passing in a function like
> > (defn B-Gen [] (+ *A* 1)) to create a new binding to B but I quickly
> > realized this would be a bug inducing nightmare. If I forget to
> > include one of the derived values in the binding or put them in the
> > wrong order then I would get the wrong value.
>
> > So what I currently do is:
> > (def *A* 3) ; A bogus value that will later be rebound
> > (defn B [] (+ *A* 3))
>
> > The good news is, that this works and doesn't require any book
> > keeping.
>
> > The bad news is that it's ugly. If I want to do something trivial like
> > divide B by 2 I have to call B as a function(/ (B) 2) instead of the
> > more natural (/ B 2). And of course this approach is pretty
> > unfortunate from a performance perspective as I'm constantly having to
> > recalculate what are effectively static values. Yes, I could use
> > memoization but many of these values are pretty trivial (usually just
> > algebra equations) and I suspect the overhead of memoization exceeds
> > the perf improvement.
>
> > But in any case the whole approach of having to take what really are
> > static values and turn them into functions feels really hacky. So my
> > guess is that I'm thinking about this problem the wrong way. I'm stuck
> > in my old imperative/OO constructor world.
>
> > What's the right way to think about primary values that will be
> > rebound (once) that then have dependent values that need to be
> > recalculated when that rebinding happens?
>
> >      Thanks,
>
> >              Yaron
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To po

Re: newbie question: Please help me stop creating constructors

2010-02-19 Thread Yaron

> Looks pretty good to me. I like your use of preconditions and the  
> number of tests. I think your indentation is a little deep (I go for  
> two spaces, myself), and I never use :Capital keywords, but otherwise  
> great.
>
The indentation was just what the Clojure plugin for Eclipse was set
to by default.

As for capitalization I've never been completely clear on what the
normal naming rules in Clojure are.

> You might be interested in the `are` macro to make your test code  
> simpler:
>

Thanks for pointing this out. Very useful. I've already started
adapting some of my tests.

> One suggestion:
>
> Rather than having two phases of derived args, and calling functions  
> with arguments like:
>
>   (total-house-depreciation args-and-mib)
>
> I'd save that step and adjust total-house-depreciation, year-sold,  
> etc. to take an additional months-in-business argument:
>
> (defn total-house-depreciation
>     "The total amount of depreciation on the rental property taken  
> over the period we were in business"
>     [args months-in-business]
>     ...)
>
> Then you can change your derived-args function to:
>
> (defn derived-args
>         [{:keys [months-to-find-tenant months-in-lease lease-cycles months-to-
> sell] :as args}]
>    (assoc args
>      :months-in-business (months-in-business months-to-find-tenant  
> months-in-lease lease-cycles months-to-sell)
>      :total-house-depreciation (total-house-depreciation args months-
> in-business)
>      :year-sold (year-sold args months-in-business)
>      :months-actively-renting (months-actively-renting months-to-find-
> tenant months-in-lease lease-cycles)))
>
> No lets at all.

The reason why I didn't make months-in-business an explicit arg for
total-house-depreciation and year-sold is because both functions are
thin wrappers for underlying functions that take args. So if I broke
out months-in-business at the top I'd just have to invent the
equivalent of the args-and-mib variable farther down to give the
functions they are wrapping what they are expecting.

BTW, the only place I had to use let in anything even like this manner
was derived-args. Everywhere else I can just pass args with no voodoo,
no lets, nothing. All the 'voodoo' is just in derived-args and
creating derived-args.

> You'll see then that it's a small step from there to my suggested  
> "functional" end game, which eliminates the passing of the args map  
> altogether: derived-args would extract all the named arguments and  
> pass just the specific ones to each function. No big deal, though;  
> there are advantages to the map approach.
>

This is the one paragraph I'm not sure I completely follow. derived-
args is a pretty dumb (as in intelligence) function. It just takes the
core args (the ones passed in by the user) and augments them with some
convenience values that are static for the whole run of the
calculator.

So without the map top level functions like Rent, Sell,
MonthlyRentalProfit, etc. would literally need to take 30+ arguments
(I'm not exaggerating btw). My root function looks like:

(defn run-calculator
   [args]
   (let [derived-args (derived-args args)]
(- (rent derived-args) (sell derived-args

I have to think that's preferable to submitting 30+ arguments to rent
and sell.

Or were you suggesting a different approach?

> Looking good!
>
> -R

   Mega thanks!!!

Yaron

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


Re: newbie question: Please help me stop creating constructors

2010-02-28 Thread Yaron
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)
   house-sales-price (house-sales-price house-sales-price-0
inflate)
   buying-agent-fee (agent-fee inflate buying-agent-fee-type
buying-agent-fee-number house-sales-price)
   selling-agent-fee (agent-fee inflate selling-agent-fee-type
selling-agent-fee-number house-sales-price)
   other-sales-fees (other-sales-fees other-sales-fees-0
inflate)
   remaining-loan-balance (remaining-loan-balance months-in-loan
original-loan-amount monthly-loan-interest loan-month-at-start)
   house-sale-expenses (house-sale-expenses house-sales-price
excise-tax buying-agent-fee selling-agent-fee other-sales-fees
remaining-loan-balance)
   house-sale-profit (house-sale-profit house-sales-price house-
sale-expenses)
   months-in-business (months-in-business months-to-find-tenant
months-in-lease lease-cycles months-to-sell)]
(sell house-sale-profit real-monthly-opportunity-cost months-in-
business)))

Writing the previous wasn't much fun and I recognized that I would
have to build the equivalent for testing all the various sub-functions
and I can only imagine what trying to do any kind of refactoring or
adding new functions would be like.

But then it occurred to me that all I was really doing was building up
a parse tree and that is something that computers are really good at.
So why not just have the computer do the work for me? So I wrote a
function called fill-map. It takes a keyword that maps to the name of
a function and a map that contains all the user arguments. It turn
returns a map that contains the submitted function and all of its
dependent functions. (Having the whole map including the dependent
functions is extremely useful for testing)

(defn fill-map
 ([func-name-keyword filled-map] (fill-map func-name-keyword filled-
map []))
 ([func-name-keyword filled-map ancestorvector]
  {:pre [(keyword? func-name-keyword) (map? filled-map) (vector?
ancestorvector)]}
  (if (contains? filled-map func-name-keyword)
   filled-map
   (do
(throw-if-in-seq func-name-keyword ancestorvector)
(let [func-name-symbol (keyword-to-symbol func-name-keyword)
  func (func-keyword-to-func-pointer func-name-keyword)
  func-arguments (func-keyword-to-func-keyword-arglist func-
name-keyword)
  ancestorvector (conj ancestorvector func-name-keyword)
  filled-map (reduce #(fill-map %2 %1 ancestorvector) filled-
map func-arguments)]
 (assoc filled-map func-name-keyword (apply func (map #(filled-
map %1) func-arguments

I also wrote:
(defn stack-em
 [func-name-keyword filled-map]
 ((fill-map func-name-keyword filled-map) func-name-keyword))

So now I can just say:

(defn sell-calculator
 [userargs]
 (stack-em :sell userargs))

The previous creates the same parse map as I manually created above
but in a fully automated fashion. And if I change any of the
signatures, dependencies, stick in new things, etc. it's no problem,
everything gets automatically regenerated.

You can see the whole program at 
http://www.goland.org/simple-reverse-rent-or-sell.clj

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

  Thanks,

   Yaron

On Feb 19, 10:15 pm, Richard Newman  wrote:
> > I have to think that's preferable to submitting 30+ arguments to rent
> > and sell.
>
> > Or were you suggesting a different approach?
>
> The different approach only works with a different approach :)
>
> The way you've structured run-calculator, using the map is best,  
> because 30 arguments is crazy.
>
> Your need to pass 30 arguments to rent and sell because they need to  
> obtain or compute all of their intermediate values. You have a tre

Re: newbie question: Please help me stop creating constructors

2010-03-01 Thread Yaron
I don't think that dataflow works quite right in my case because, if I
understood Mr. Straszheim's posts correctly then dataflows can't have
cycles and I have cycles all over the place. Unfortunately this isn't
visible in the example I gave because I used Sell which doesn't have
cycles. Rent on the other hand is recursive and cyclic.

On Mar 1, 7:31 am, Richard Newman  wrote:
> >> but complexity of such expressions quickly grows as dependencies
> >> between variables become more complex. Is there any
> >> technique/framework for handling such calculations automatically? I
> >> have a vague impression that this is what logic programming languages
> >> are about. How would one implement such calculations in Clojure?
>
> As Johnny mentioned: this is a solver. Doing it in Clojure means  
> writing something rather more complicated than a simple calculator!  
> Clojure is not a logic programming language.
>
> You might find a cell/dataflow framework useful, which essentially  
> gives you spreadsheet-like dataflow:
>
>    
>
> best introduced in its original Common Lisp form:
>
>    
>
> but you'll still have to do some manual decision-making. (Just like in  
> a spreadsheet, you have to write the formulae...)
>
> You might also (depending on how things fall out) find some kind of  
> table-based or multimethod-based approach to be adequate (e.g., making  
> two different kinds of `sell` evaluation based on whether some value  
> is nil). That will reduce the number of explicit branches in your code.
>
> If neither of those helps, then your best bet is to spend a little  
> time with, say, Mathematica, Excel, and Prolog (or one of its  
> successors). Those might well be better systems for handling this kind  
> of web of dependencies.
>
> If you want a Lisp syntax for Prolog, try Allegro Common Lisp.
>
> http://www.franz.com/products/prolog/index.lhtml

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


swank, clojure.repl and my fading sanity

2011-11-14 Thread Yaron
So when I start a repl from the command line things like doc and
source work just fine.

But when I start a repl inside of aquamacs and swank clojure (1.3.3)
(installed via lein plugin) and clojure (1.3.0) via m-x clojure-jack-
in those function/macros don't work at all. For example, if I try (doc
str) I get the error "unable to resolve symbol: doc in this
context" [Thrown class java.lang.RuntimeException].

I tried (ns-all) but it doesn't show clojure.repl as being available.
(use clojure.repl) just gets me a [Thrown class
java.lang.ClassNotFoundException].

Note that the REPL in SWANK works in general. I can evaluate my
functions and they work.

So how do I get clojure.repl to load in SWANK?

 Thanks,

   Yaron

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


Re: swank, clojure.repl and my fading sanity

2011-11-15 Thread Yaron
Sean, Phil, thanks! Although now I realize that if I'm going to use
Emacs then I'm going to have to learn the commands. Right now I'm
trying to use 
http://www.pchristensen.com/blog/articles/public-beta-open-for-ultimate-n00b-slimeemacs-cheat-sheet/.
We'll see how that goes.

  Thanks!

  Yaron

On Nov 15, 5:37 pm, Phil Hagelberg  wrote:
> On Mon, Nov 14, 2011 at 11:06 PM, Sean Corfield  
> wrote:
> > Add the following to your ~/.lein/user.clj:
>
> > ;; ~/.lein/user.clj
> > (if (>= (.compareTo (clojure-version) "1.3.0") 0)
> >  (do (use 'clojure.repl)
> >      (use 'clojure.java.javadoc)))
>
> This will work, but most of the functionality of clojure.repl isn't
> very useful in slime. C-c C-c d gets you docs, and M-. gets you
> source.
>
> -Phil

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