As others have noted, this is pretty much what monads are made for. I've
found Brian Marick's "Functional Programming for the Object-Oriented
Programmer"'s chapter on monads really good at teaching how to recognize
situations where monads would be a good fit.
For this specific use-case, you can pr
t; c (do-c . a . b)]
> (log/info "Success" {:a a
>:b b
>:c c})
> c)
>
> Now, say each steps could possibly throw an exception. So you want to
> try/catch the let bindings:
>
> (try
> (let [a (do-a
Now that bertschi mentioned Haskell and side-effects, I noticed that the
problem we have here totally looks like a monad:
we have several steps of side-effecting computation, and each of them can
fail, and when this happens you want to handle the failure while keeping
the previous bindings.
Now, w
On Monday, October 2, 2017 at 11:04:52 PM UTC+2, Didier wrote:
>
> > Even in an impure language such as Common Lisp we frown on such LET forms
>
> True, but as far as I know, in Common Lisp, the condition handler is
> always in scope of where the error happened, so I wouldn't face this
> proble
> Even in an impure language such as Common Lisp we frown on such LET forms
True, but as far as I know, in Common Lisp, the condition handler is always in
scope of where the error happened, so I wouldn't face this problem.
I also struggle to split this up into functions without making it even mo
en in an impure language such as Common Lisp we frown on such LET forms.
I believe it was Lisp legend Paul Graham who suggested we imagine a tax on
LET.
Sometimes while sorting out something complex I do solve it in a series of
LET bindings, but once I understand what I am about I am able to ad
> On Oct 1, 2017, at 9:21 PM, Didier wrote:
>
> I can't emphasize enough the utility of the interceptor chain pattern, as
> employed heavily in pedestal.
>
> Interesting... Its almost like a workflow framework, but for simpler in code
> workflows. I'm reluctant to have a dependency on pedest
Didier, I've done something similar a few times just using core.async -- no
extra deps required ;-)
d
On 1 October 2017 at 23:21, Didier wrote:
> I can't emphasize enough the utility of the interceptor chain pattern, as
>> employed heavily in pedestal.
>>
>
> Interesting... Its almost like a w
Hi Didier
The interceptor pattern is pretty tiny, certainly small enough to copy from
project to project if you wanted. You can see re-frame's implementation
here:
https://github.com/Day8/re-frame/blob/master/src/re_frame/interceptor.cljc
which
is only around 100 SLOC. That doesn't handle exceptio
>
> I can't emphasize enough the utility of the interceptor chain pattern, as
> employed heavily in pedestal.
>
Interesting... Its almost like a workflow framework, but for simpler in
code workflows. I'm reluctant to have a dependency on pedestal just for
this though.
On Sunday, 1 October 201
> On Sep 30, 2017, at 3:14 PM, Didier wrote:
>
> Is there another way to execute a set of complex steps which does not rely on
> let and can be try/catched in the manner I describe?
I can't emphasize enough the utility of the interceptor chain pattern, as
employed heavily in pedestal.
I use
I've seen this, I was still curious if the reason I was facing the issue
was that let is simply the wrong tool for my use case or not.
If let is the correct tool, I would propose that clojure.core should had a
try/catch where the catch is in scope of the try. I feel the reason this is
contrived
I've used try-let (link below) for this, it's worked great!
https://github.com/rufoa/try-let
--
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
(do-b . a . .)
c (do-c . a . b)]
(log/info "Success" {:a a
:b b
:c c})
c)
Now, say each steps could possibly throw an exception. So you want to
try/catch the let bindings:
(try
(let [a (do-a ...)
b (do-b . a . .)
Think about values first, symbols after.
Symbols are accessory, not values, values are the only things that exist at
runtime.
Symbols are only there for you poor human (I include myself in this statement)
to grasp
roughly what is going on by tracking intermediate values with names. The names
y
On 12 February 2015 at 02:06, gvim wrote:
>
> That explains it but I think Clojure's syntax is misleading here. Without
> knowledge of this magic the mind doesn't readily translate:
>
> (let [x 1
> x (inc x)
> x (inc x)
> x (inc x)]
>x)
>
> into:
>
> (let [x 1]
>
2015-02-12 3:06 GMT+01:00 gvim :
>
> That explains it but I think Clojure's syntax is misleading here. Without
> knowledge of this magic the mind doesn't readily translate:
>
>
In some other lisps, clojure's let is called let* for this reason. Their
let binds only in parallel, similar to clojure's
I think that, from a user perspective, the important difference from
mutation to shadowing is, that outer x is available even in the inner
context, if captured by a closure.
Likewise, a second thread, that runs an outer closure, would see the
original x.
Observe:
(let [x :outer
f (fn [] x)
On 12/02/2015 01:53, Ben Wolfson wrote:
The multiple-binding form of let can be recursively transformed into
nested lets:
(let [name1 value1 name2 value2 ... name value] body)
>
(let [name1 value1] (let [name2 value2] ... (let [name value] body)))
All you're doing with your let form is sha
Local bindings are immutable.
Your example demonstrates lexical shadowing of bindings.
This is an equivalent program semantically.
(let [x 1
x_1 (inc x)
x_2 (inc x_1)
x_3 (inc x_2)]
x_3)
By the rules of lexical scoping, you cannot access the first `x` but it is
never mutat
(let [x 0
f #(println x)
x 1
g #(println x)
x 2]
(f)
(g)
x)
there is no mutation of x, only scope shadowing hiding the other binding. Most
functional languages (all that I know) allow shadowing.
--
You received this message because you are subscribed to the Goo
The multiple-binding form of let can be recursively transformed into nested
lets:
(let [name1 value1 name2 value2 ... name value] body)
>
(let [name1 value1] (let [name2 value2] ... (let [name value] body)))
All you're doing with your let form is shadowing the name; there's no
mutation. If y
On 12/02/2015 01:44, Laurens Van Houtven wrote:
Hi,
You’re confusing mutation with single assignment. You’re not mutating anything:
1 is still 1, 2 is still 2; you’re just assigning the same name to different
numbers. The numbers themselves are immutable.
It's x that bothers me, not the val
Hi,
> On Feb 11, 2015, at 5:42 PM, gvim wrote:
>
> Why is this possible in a language based on immutability:
>
> (let [x 1
>x (inc x)
>x (inc x)
>x (inc x)]
> x)
>
> ;;=> 4
>
> Maybe under the hood (ie. memory registers/pointers etc.) this isn't strictly
> mutation
Why is this possible in a language based on immutability:
(let [x 1
x (inc x)
x (inc x)
x (inc x)]
x)
;;=> 4
Maybe under the hood (ie. memory registers/pointers etc.) this isn't
strictly mutation but as a relative newcomer to Clojure I find it goes
against the grain
Excellent post, thank you for that.
--
--
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 unsubscr
> If there's another reason then I'm hoping someone will correct me, but I
> can't think of any other reasons at the moment.
Since Clojure doesn't do tail call elimination implementing let atop fn would
also use up stack.
I believe many or all Schemes (which are required by the spec to eliminat
On 1/20/14, 12:38 PM, Andy Smith wrote:
> Hi,
>
> (let bindings form) is a special form. As I understand it, let can be
> reformulated in terms of functions e.g.
>
> (let [x 2] (* x 20)) equivalent to ((fn [x] (* x 20)) 2)
> (let [x 3 y (* x x)] (- y x)) equivalent to ((f
Hey Andy!
On Mon, Jan 20, 2014 at 12:38:23PM -0800, Andy Smith wrote:
> So if we can always reformulate in this was, why cant let be implemented as
> a macro rather than a special form?
It can. Quite easily, in fact:
(defmacro my-let [bindings & body]
(if (empty? bindings)
`
> Hi,
>
> (let bindings form) is a special form. As I understand it, let can be
> reformulated in terms of functions e.g.
>
> (let [x 2] (* x 20)) equivalent to ((fn [x] (* x 20)) 2)
> (let [x 3 y (* x x)] (- y x)) equivalent to ((fn [x] ((fn [x y] (- y x)) x
> (* x x)
typo : was=way
--
--
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,
Hi,
(let bindings form) is a special form. As I understand it, let can be
reformulated in terms of functions e.g.
(let [x 2] (* x 20)) equivalent to ((fn [x] (* x 20)) 2)
(let [x 3 y (* x x)] (- y x)) equivalent to ((fn [x] ((fn [x y] (- y x)) x
(* x x))) 3)
So if we can always reformulate
ither:
* Short;
* Long let bindings, short body;
* Mid-size;
* Mostly a (loop ...); or
* Mostly a body that mutates stuff, likely a big (doto ...) or (dosync ...)
or a series of send-off, swap!, etc.
The last and some of the others being not pure, so usually at the periphery
of the system. Controller
Thanks, very interesting point. It's a shame this is not available in the
clojure docs - very useful for newcomers as me.
Is it fair to say that let bindings is good/recomended to put all the code
and the main body is used primarily for returning results of the function?
Cheers,
More likely it has to do with simply naming many of the intermediate
results in a calculation. That often results in long let bindings with
short let bodies. I've written many a function that's basically
(defn foo [x]
(let [stuff
more stuff
yet more stuff
r
I'm currently working with tree-seq function from clojure.core and there is
one thing I'm struggling to understand... Could you please explain why
pretty much all of the body of the function sits within 'let binding' and
not in the 'let body' where only (walk root) is placed?
Has it something to
On Sat, Jul 30, 2011 at 9:07 PM, Alan Malloy wrote:
> (get :foo argmap__5673__auto 42) is the right way to solve this
> problem.
Is another way to solve it, yes, and a good one.
> Or if, as in the current example, you want to destructure a map with
> lots of defaults, simply:
>
> (let [{:keys [f
On Jul 29, 2:02 pm, Ken Wesson wrote:
> (fn [& args]
> (let [argmap__5673__auto (#'some-ns/parse-args args)
> foo (or (:foo argmap__5673__auto) 42)
> bar (or (:bar argmap__5673__auto) nil)
> ...]
> (body goes here)))
> where you define a private parse-args function in
On Sat, Jul 30, 2011 at 7:29 AM, Sam Aaron wrote:
>> (fn [& args]
>> (let [foo (some logic goes here)
>> bar (some logic goes here)
>> ...]
>> (body goes here)))
>
> I just finished implementing a solution and it looks exactly like this.
> You're absolutely right - this is preci
Hi Ken,
On 29 Jul 2011, at 22:02, Ken Wesson wrote:
>> P.S. Thanks everyone for your help so far. My brain is overheating but I am
>> learning a lot.
>
> You're welcome.
>
> To do what you're proposing you will probably need the emitted
> function to look like:
>
> (fn [& args]
> (let [foo (s
> P.S. Thanks everyone for your help so far. My brain is overheating but I am
> learning a lot.
You're welcome.
To do what you're proposing you will probably need the emitted
function to look like:
(fn [& args]
(let [foo (some logic goes here)
bar (some logic goes here)
...]
amp; ~args]
(let ~(binding-vec args)
~@forms
((magic-fn (+ size 10)) 1 2) ;=> Unable to resolve symbol: size in this context
>
> (defmacro with-arg-params [bindings & body]
> (let [bindings (apply array-map bindings)]
>`(fn
> ~@(for [i (range (inc
z)
>
> a would now be bound to a fn which I could call:
>
> (yo 1 2 3) ;=> 6
>
> I could also call it with fewer args than expected:
>
> (yo 1 2) ;=> 5
>
> this works because bad has a default of 2.
(defmacro with-arg-params [bindings & body]
(let [bin
On 29 Jul 2011, at 12:11, Ken Wesson wrote:
>
> Why not just (vec (interleave names (take (count names) (repeat
> `(count ~foos)?
>
That seems to blow up:
(defn binding-vec [foos]
(vec (interleave names (take (count names) (repeat `(count ~foos))
(defmacro magic-fn
[& forms]
(let
On Fri, Jul 29, 2011 at 6:57 AM, Sam Aaron wrote:
> However, something like the following doesn't work:
>
> (defn binding-vec [foos]
> `(vec (interleave ~names ~(take (count names) (repeat '`(count ~foos))
>
> A, because the above code is probably incorrect (I just cobbled it together
> for
Hi there,
On 29 Jul 2011, at 10:05, Alan Malloy wrote:
>
> (defn binding-vec [foos]
> ['size `(count ~foos)])
>
> (defmacro magic-fn
> [& forms]
> (let [args (gensym 'args)]
>`(fn [& ~args]
> (let ~(binding-vec args)
> ~@forms
>
> ((magic-fn (+ size 10)) 1 2) ;=> 12
Ac
Hi Alan,
On 29 Jul 2011, at 10:05, Alan Malloy wrote:
>>
>> Sorry, I was just trying to simplify things to try and get directly to the
>> meat of the problem.
>
> No apologies needed - reducing to a simple case is great. But here,
> the simplification was probably too severe.
>
Sorry, I'm Eng
On Jul 29, 1:49 am, Sam Aaron wrote:
> On 29 Jul 2011, at 07:22, Ken Wesson wrote:
>
> > On Fri, Jul 29, 2011 at 12:49 AM, Jeff Rose wrote:
> >> I don't think it's very typical to pass a form to a function, unless
> >> you plan on using eval at runtime.
>
> > Or it's a function called by a macro
On 29 Jul 2011, at 00:46, Kent wrote:
> I'm not sure what you're trying to do with this and, based on that
> ignorance, I'm not sure I think it's a great idea. Maybe you are being
> a bit crazy, and maybe your a genius. Who am I to say?
>
> Here is a function that does what you want. The only
On 29 Jul 2011, at 07:22, Ken Wesson wrote:
> On Fri, Jul 29, 2011 at 12:49 AM, Jeff Rose wrote:
>> I don't think it's very typical to pass a form to a function, unless
>> you plan on using eval at runtime.
>
> Or it's a function called by a macro to do some processing of forms.
Yep, this is p
On Fri, Jul 29, 2011 at 12:49 AM, Jeff Rose wrote:
> I don't think it's very typical to pass a form to a function, unless
> you plan on using eval at runtime.
Or it's a function called by a macro to do some processing of forms.
--
Protege: What is this seething mass of parentheses?!
Master: You
I don't think it's very typical to pass a form to a function, unless
you plan on using eval at runtime. If it doesn't need to happen at
runtime, then you'd do this with a macro approximately like this:
user=> (defmacro bar [f] `(fn [& args#] (let [~'size (count args#)]
~f)))
#'user/bar
user=> (ba
On Jul 28, 3:48 pm, Sam Aaron wrote:
> Hi there,
>
> I'm trying to create a fn which does the following:
>
> * returns a fn which takes an arbitrary number of args
> * calls a helper fn, passing the incoming args returning a vector of
> alternating symbols and vals
> * creates a let form using th
On Thu, Jul 28, 2011 at 6:48 PM, Sam Aaron wrote:
> Hi there,
>
> I'm trying to create a fn which does the following:
>
> * returns a fn which takes an arbitrary number of args
> * calls a helper fn, passing the incoming args returning a vector of
> alternating symbols and vals
> * creates a let
I'm not sure what you're trying to do with this and, based on that
ignorance, I'm not sure I think it's a great idea. Maybe you are being
a bit crazy, and maybe your a genius. Who am I to say?
Here is a function that does what you want. The only difference is
that my function also takes the "bin
Hi there,
I'm trying to create a fn which does the following:
* returns a fn which takes an arbitrary number of args
* calls a helper fn, passing the incoming args returning a vector of
alternating symbols and vals
* creates a let form using the vector of alternating symbols and vals returned
b
56 matches
Mail list logo