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 <holyg...@gmail.com> 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  
> them, whatever
> * There are no global values or bindings
> * You can name each intermediate value using let; your main function  
> can essentially be a sequential set of intermediate calculations, just  
> like your PDF.

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

Reply via email to