Re: ANN: ClojureScript 0.0-2496, cljs.test - a clojure.test port

2014-12-17 Thread James MacAulay
Looks great, thanks so much!

I was happy to see the "TODO: support async" comment in test.clj, as I am 
currently using Chas Emerick's clojurescript.test for very async-heavy stuff. I 
ended up writing a macro which I think improves the ergonomics of portable 
async testing quite a bit:

https://github.com/jamesmacaulay/zelkova/blob/32fdcecd74e5fa51a6e710625aa4e59abb6aa25e/src/cljx/jamesmacaulay/async_tools/test.cljx#L7-L16

...which is used like this:

https://github.com/jamesmacaulay/zelkova/blob/32fdcecd74e5fa51a6e710625aa4e59abb6aa25e/test/cljx/jamesmacaulay/zelkova/signal_test.cljx#L66-L82

I really like writing async tests like this; very little fuss. Maybe once 
cljs.test has async support, a testing macro like this could go into core.async?

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


Re: Zelkova: Elm-style FRP for Clojure and ClojureScript

2014-12-07 Thread James MacAulay
On Sunday, 7 December 2014 19:41:58 UTC-5, nchurch wrote:
>
> Did you ever look into Hoplon/Javelin?  Haven't heard much about it on 
> this group recently, and curious why
>

As it happens, Alan Dipert gave a great remote presentation on Hoplon to my 
local Clojure user group (Clojure Toronto) in October, a few days after I 
released Zelkova 0.1.0. At that point I was aware of Hoplon and Javelin, 
but hadn't realized until Alan's presentation how much Javelin's 
implementation had in common with Elm (from what I understand, the way it 
synchronizes event ordering is very similar, though I haven't looked at 
Javelin's code myself).

The programming model is of course rather different, though, with a 
different set of tradeoffs. There's a lot that I like about Javelin and the 
"cells" model in general, and Alan's talk got me thinking about the 
potential for implementing a cells-style interface on top of Zelkova. I 
haven't actually pursued that yet though.

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


Re: Zelkova: Elm-style FRP for Clojure and ClojureScript

2014-12-07 Thread James MacAulay
On Sunday, 7 December 2014 02:01:33 UTC-5, eric wrote:
>
> Interesting, I think this here goes along the same lines: 
> https://github.com/logaan/promise-stream
>  
>

Cool, I'll check that out. Hadn't seen that one before. I was also happy to 
see Rich Hickey talking about the upcoming Promise Channels in his recent 
Clojure/conj talk.

So your motivations seem all good but I have a gut feeling that by 
> embracing Elm you are painting yourself in a corner. As in, it seems neat 
> but eventually you hit some brick wall that can't be overcome and you 
> realize you have to go back and take off into yet another direction. I have 
> refrained from going down the Elm path for that reason.
>

Let's say the worst-case scenario is that there's actually no good way to 
do large applications using Elm-style FRP top-to-bottom. Even if that ends 
up being the case, those static signal graphs are still really nice for 
managing the state of individual components of an application. Having a 
number of distinct graphs connected by some other means of managing state 
still seems like a good situation to me and something worth pursuing.

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


Re: Zelkova: Elm-style FRP for Clojure and ClojureScript

2014-12-06 Thread James MacAulay
What prompted me to write Zelkova?

The short answer is curiosity and gut feeling. The long answer:

I consider core.async (and CSP in general) to be an excellent low-level 
abstraction for coordinating concurrency, but I feel like it relies way too 
much on mutating operations for me to want to use it much directly in 
application code. Like any other mutating code, I want to push it to the 
edges as much as possible. Along those lines, I had previously explored 
using core.async with JS promises [1] and "async futures" [2].

Promises and futures are great (pseudo-?)immutable constructs for 
representing single "eventual values", but don't really help at all with 
values that change over time. So I wanted to build an FRP library based on 
core.async, which seemed like an obviously strong foundation for FRP that 
was surprisingly under-explored as such. At first I made some initial stabs 
at modelling a system after Bacon.js, which at the time I considered more 
attractive than Elm's style of FRP. However, I was fighting too much with 
core.async to make it work, and it just felt like the wrong direction.

I decided to read Evan Czaplicki's 2012 thesis on Elm to understand that 
different perspective better, and the more I understood it the more 
compelling I found that approach. I had a very similar experience with the 
paper as Eric Normand recently described [3], and that Concurrent ML code 
was just begging to be ported to core.async :)

The fact that Elm's signal graphs are static does present some challenges, 
but it also brings real benefits (as Evan outlines well in his talk that I 
linked in the original post). People are still figuring out how best to 
structure larger applications in Elm, but I see a lot of potential. At its 
best, Elm code is some of the clearest code I've seen, with almost zero 
"baggage" (read: incidental complexity).

Furthermore, Zelkova brings its own advantages by being embedded in and 
implemented entirely in Clojure/ClojureScript. You can reach outside the 
strictness of the signal graph whenever you need to, and continue using the 
same nice language as when you're working "from within" a graph. Needless 
to say, development in Clojure also helps immensely with implementing the 
library itself.

[1]: https://github.com/jamesmacaulay/cljs-promises
[2]: 
https://github.com/jamesmacaulay/async-tools/blob/master/test/cljx/jamesmacaulay/async_tools/core_test.cljx#L62-L82
[3]: http://www.lispcast.com/elm-frp-clojure-core-async

On Saturday, 6 December 2014 07:01:30 UTC-5, eric wrote:
>
> Hi,
>
> May I ask what prompted you to write this? A coding exercise or some 
> real-world need? I'm asking because I've been keeping an eye on FRP for a 
> while. From what I understand it's conceptually not ready for anything 
> other than toy problems yet. Like Elm's restriction on static flow graphs. 
> It's like programming without 1st class functions, you don't get very far.
>
> eric
>
> On Monday, October 20, 2014 11:56:45 AM UTC+11, James MacAulay wrote:
>>
>> I've just published an FRP library based on Elm[1]:
>>
>> https://github.com/jamesmacaulay/zelkova
>>
>> Here's what the app code looks like:
>>
>>
>> https://github.com/jamesmacaulay/zelkova/blob/4b06c49678e11e3af7b1eda7a18929a512f7753d/examples/mario/src/mario/core.cljs#L118-L133
>>
>> Right now Zelkova includes ports of Elm's Signal, Mouse, Keyboard, and 
>> Window libraries, plus part of its Time library[2]. Zelkova's signal 
>> namespace works in both Clojure and ClojureScript, but the rest only have 
>> implementations for ClojureScript in the browser.
>>
>> Elm-style FRP is a bit different from other flavours like those of Rx or 
>> Bacon.js. In particular, Elm's signal graphs are static (can't be 
>> reconfigured once they start running) and don't allow for 
>> signals-of-signals.
>>
>> Zelkova is the same way, but its signal functions actually return 
>> "recipes" for signals which don't start processing values until a "live" 
>> graph gets spawned from one of them. This allows multiple live graphs to 
>> run concurrently while sharing logical structure, and should make some 
>> things easier in the future (like porting Elm's time-travelling debugger). 
>> Theoretically this should also make it possible to compile some kinds of 
>> signal graphs into transducers instead of running them as networks of 
>> core.async channels.
>>
>> If you're interested in the differences and tradeoffs between the 
>> different forms of FRP out there, Evan Czaplicki gave an excellent talk on 
>> the subject at Strange Loop this year:
>>
&

Zelkova: Elm-style FRP for Clojure and ClojureScript

2014-10-19 Thread James MacAulay
I've just published an FRP library based on Elm[1]:

https://github.com/jamesmacaulay/zelkova

Here's what the app code looks like:

https://github.com/jamesmacaulay/zelkova/blob/4b06c49678e11e3af7b1eda7a18929a512f7753d/examples/mario/src/mario/core.cljs#L118-L133

Right now Zelkova includes ports of Elm's Signal, Mouse, Keyboard, and 
Window libraries, plus part of its Time library[2]. Zelkova's signal 
namespace works in both Clojure and ClojureScript, but the rest only have 
implementations for ClojureScript in the browser.

Elm-style FRP is a bit different from other flavours like those of Rx or 
Bacon.js. In particular, Elm's signal graphs are static (can't be 
reconfigured once they start running) and don't allow for 
signals-of-signals.

Zelkova is the same way, but its signal functions actually return "recipes" 
for signals which don't start processing values until a "live" graph gets 
spawned from one of them. This allows multiple live graphs to run 
concurrently while sharing logical structure, and should make some things 
easier in the future (like porting Elm's time-travelling debugger). 
Theoretically this should also make it possible to compile some kinds of 
signal graphs into transducers instead of running them as networks of 
core.async channels.

If you're interested in the differences and tradeoffs between the different 
forms of FRP out there, Evan Czaplicki gave an excellent talk on the 
subject at Strange Loop this year:

https://www.youtube.com/watch?v=Agu6jipKfYw

Cheers,
James

[1] http://elm-lang.org
[2] 
https://github.com/jamesmacaulay/zelkova/tree/master/src/cljx/jamesmacaulay/zelkova

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


Re: Using core.typed to guide runtime behavior?

2014-04-24 Thread James MacAulay
Thanks for the pointers, Ambrose, and thanks for core.typed!

James

On Thursday, 24 April 2014 17:24:21 UTC-4, Ambrose Bonnaire-Sergeant wrote:
>
> I haven't tried anything like this.
>
> The most obvious pitfall is core.typed currently loads lazily and collects
> type annotations only after check-ns.
>
> There's a bunch of tools for manipulating types in the checker.
>
> Thanks,
> Ambrose
>
>
> On Thu, Apr 24, 2014 at 11:18 PM, James MacAulay 
> 
> > wrote:
>
>> I'm interested in exploring the use of the types provided by core.typed 
>> to guide function behavior at runtime. Specifically, I'd like to wrap 
>> existing functions such that the resulting functions behave in different 
>> ways depending on the type signatures of each original function.
>>
>> I'm imagining a setup where I have macros that get type information from 
>> core.typed at the time of macro-expansion, and either:
>>
>> * decide entirely at macro-expansion time how a function should be 
>> wrapped based on its type, or
>> * somehow make the type information available at runtime, leaving the 
>> analysis of the types to runtime functions.
>>
>> As an example of the kind of decision I'd like to make based on types, I 
>> might look at `clojure.core/map` and say "I'll wrap `map` such that its 
>> first argument will be transformed in some particular way because the 
>> argument is a function, and the rest of the arguments will be transformed 
>> in some other way because they are collections." The reason I want to have 
>> type information for this is that I want the transformations to be 
>> dependent on the actual semantics of the original function, which is hinted 
>> at by the types. For example I can take the fact that an argument's type is 
>> some sort of collection and infer that the function is probably processing 
>> its contents; in that case I would want to transform the argument in a 
>> different way than if its type were `Any`, in which case I could conclude 
>> that even if the argument ends up being a collection at runtime, the 
>> original function must not be relying on that fact.
>>
>> Does anyone see any obvious pitfalls with this kind of thing? Any tips 
>> from the crowd? I'm not sure exactly the best way of actually "analyzing" 
>> the type signatures, but I'm hoping that I might find some tools for that 
>> in core.typed.
>>
>> Thanks for any help you can give!
>>
>> Cheers,
>> James
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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


Using core.typed to guide runtime behavior?

2014-04-24 Thread James MacAulay
I'm interested in exploring the use of the types provided by core.typed to 
guide function behavior at runtime. Specifically, I'd like to wrap existing 
functions such that the resulting functions behave in different ways 
depending on the type signatures of each original function.

I'm imagining a setup where I have macros that get type information from 
core.typed at the time of macro-expansion, and either:

* decide entirely at macro-expansion time how a function should be wrapped 
based on its type, or
* somehow make the type information available at runtime, leaving the 
analysis of the types to runtime functions.

As an example of the kind of decision I'd like to make based on types, I 
might look at `clojure.core/map` and say "I'll wrap `map` such that its 
first argument will be transformed in some particular way because the 
argument is a function, and the rest of the arguments will be transformed 
in some other way because they are collections." The reason I want to have 
type information for this is that I want the transformations to be 
dependent on the actual semantics of the original function, which is hinted 
at by the types. For example I can take the fact that an argument's type is 
some sort of collection and infer that the function is probably processing 
its contents; in that case I would want to transform the argument in a 
different way than if its type were `Any`, in which case I could conclude 
that even if the argument ends up being a collection at runtime, the 
original function must not be relying on that fact.

Does anyone see any obvious pitfalls with this kind of thing? Any tips from 
the crowd? I'm not sure exactly the best way of actually "analyzing" the 
type signatures, but I'm hoping that I might find some tools for that in 
core.typed.

Thanks for any help you can give!

Cheers,
James

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


Re: ClojureScript browser REPL goes bonkers after it evals

2013-07-07 Thread James MacAulay
I was consistently experiencing this issue, and upgrading to leiningen 
2.2.0 fixed it for me. The root issue was in nrepl:

http://dev.clojure.org/jira/browse/NREPL-39

It was fixed in nrepl-0.2.3, which got into leiningen-2.2.0 via reply-0.2.0.


On Tuesday, 26 February 2013 07:55:01 UTC-5, David Nolen wrote:
>
> Feel free to open a ticket in JIRA. More details would be helpful and a 
> patch would be nice. Thanks!
>
> On Monday, February 25, 2013, Bobby Wang wrote:
>
>> Update: this seems to only happen if I start the CLJS REPL inside a CLJ 
>> REPL. If I start straight from the command line (ie. lein trampoline 
>> cljsbuild repl-listen) it's fine.
>>
>> On Monday, 25 February 2013 19:22:06 UTC-5, Bobby Wang wrote:
>>>
>>> Hi,
>>>
>>> Sometimes when I start the CLJS browser REPL and evaluate something like 
>>> js/alert, the alert runs fine, but after a few seconds it goes into an 
>>> infinite loop while repeatedly printing "*ClojureScript:cljs.user> 
>>> java.io.IOException: Write end dead*".
>>>
>>> The same thing happens on ClojureScript One, which I think uses older 
>>> dependencies.
>>>
>>> Any idea what might be wrong?
>>>
>>> My setup:
>>>
>>> * clojure 1.4.0
>>> * clojurescript 0.0-1586
>>> * lein-cljsbuild 0.3.0
>>> * Mac OS X 10.8.2
>>> * Java 1.6.0_41 that came with OS X
>>> * Also tried to install Oracle's Java 7, but it doesn't seem to work out 
>>> of box yet
>>>
>>> Much appreciated,
>>>
>>> Bobby
>>>
>>
>>  

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




Re: Screencast: Clojure development with Sublime Text 2

2013-05-19 Thread James MacAulay
I just noticed a little caveat on my suggestion of copying over 
Main.sublime-menu and editing it. It'll use the updated settings when you 
select the Clojure REPL from the menu (Tools > SublimeREPL > Clojure > 
Clojure), but if you start the REPL from the command palette (cmd-shift-P) 
then it'll use the original settings file from the package and ignore your 
edited version.

If you want to be able to use your new settings with keyboard shortcuts or 
the command palette, I only know of two options:

* edit the SublimeREPL package files in-place (I try to avoid this).
* copy over the whole config/Clojure directory from the SublimeREPL package 
to the User package, and edit the files so that you have a new lein2 
command which is named differently from the existing Clojure commands.

I can't figure out how to customize the *existing* Clojure REPL commands 
solely from the User package; copying all the files and leaving them as-is 
ends up just making duplicates of the commands.

On Sunday, 19 May 2013 09:40:10 UTC-4, Jim foo.bar wrote:
>
> ooo thanks a lot :) 
>
> quick question...how did you tell sublime to use lein2 instead of lein ? 
>
> Jim 
>
>
> On 18/05/13 21:36, James MacAulay wrote: 
> > This is a little show-and-tell I recorded today: 
> > 
> > http://www.youtube.com/watch?v=wBl0rYXQdGg 
> > 
> > Hopefully it's useful for some of you. Feedback welcome! 
> > 
> > Cheers, 
> > James 
> > -- 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clo...@googlegroups.com 
> > Note that posts from new members are moderated - please be patient 
> > with your first post. 
> > To unsubscribe from this group, send email to 
> > clojure+u...@googlegroups.com  
> > For more options, visit this group at 
> > http://groups.google.com/group/clojure?hl=en 
> > --- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To unsubscribe from this group and stop receiving emails from it, send 
> > an email to clojure+u...@googlegroups.com . 
> > For more options, visit https://groups.google.com/groups/opt_out. 
> > 
> > 
>
>

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




Re: Screencast: Clojure development with Sublime Text 2

2013-05-19 Thread James MacAulay
Jonathan: thanks, that's great! I'll add a note to the video mentioning 
that a patch is on the way. Next time I'll submit an issue :)

Glen: yup, I just submitted a pull request yesterday 
(https://github.com/masondesu/sublime-paredit/pull/6)

Jim: I only have leiningen 2 installed, so that's what I get with the plain 
old "lein" command. I just added a file called Main.sublime-menu to my ST2 
settings gist, which is just taken from the SublimeREPL package:

https://gist.github.com/jamesmacaulay/5457344#file-main-sublime-menu

If you put it in your User package, you can edit the "cmd" option to use 
whichever REPL command you want.

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




Screencast: Clojure development with Sublime Text 2

2013-05-18 Thread James MacAulay
This is a little show-and-tell I recorded today:

http://www.youtube.com/watch?v=wBl0rYXQdGg

Hopefully it's useful for some of you. Feedback welcome!

Cheers,
James

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




Re: I tripped out

2013-05-05 Thread James MacAulay
Yeah. It seems like the logical extension of this would be to allow (fn args 
expr) to be equivalent to (fn [& args] expr)...but I'm not sure how useful that 
would actually be.

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




[ANN] shopify-clj

2013-03-13 Thread James MacAulay
I work at Shopify  and this has been my weekend 
project for a little while now:

https://github.com/jamesmacaulay/shopify-clj

It's a library for interacting with shops through our API. It includes a 
Friend workflow and an API wrapper based on clj-http with a custom 
middleware stack.

The Shopify App Store  has examples of how other 
people have used the API to extend the capabilities of our customers' 
shops. Some of these apps are built especially for our platform, and some 
are integrations with existing services which just go really well with a 
Shopify shop . Some of them are free, 
some of them hook into our billing 
system, 
and some of them use their own solution for getting paid.

This is my first "real library" in Clojure, and I would *love* to get 
feedback from you folks about the choices I've made. It's been a great 
learning experience and I've tried hard to play to the strengths of the 
language.

More to come in 0.2.0 and beyond:

   - a leiningen template for Shopify web apps
   - validations, or at least better ways of working with remote validation 
   errors
   - functions to help with handling 
webhooks

Cheers and happy coding,
James

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




Re: Like "if", but it composes functions

2013-02-20 Thread James MacAulay
Ben: of course, haha...making it a macro seems rather silly now :P

Alan: I didn't know about useful before, thanks for the pointer! fix and 
to-fix look great.

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




Like "if", but it composes functions

2013-02-19 Thread James MacAulay
Sometimes I find myself writing code like this:

(defn magnify [n] (if (pos? n) (inc n) (dec n)))

...and I want to get rid of all those "n"s. I've looked for a macro like 
this, but couldn't find it, so I wrote it:

https://gist.github.com/jamesmacaulay/4993062

Using that, I could re-write the above like this:

(def magnify (iffn pos? inc dec))

I can imagine a condfn macro, too:

(def magnify2 (condfn pos? inc
  neg? dec
  :else identity)

Has this kind of conditional function composition been explored much? I 
couldn't find anything like it in the standard library, but maybe I wasn't 
looking hard enough.

Cheers,
James

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




poker-hands

2013-02-14 Thread James MacAulay
A little library to score poker hands:

https://github.com/jamesmacaulay/poker-hands

Feedback would be great!

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




Re: Combining Complement and Not

2012-11-06 Thread James MacAulay
I'd say the simplest answer is just that functions *are* values, they are 
never logical-false, and (not) is based on logical falseness. Giving (not) 
a special case for functions would make it less composable by trying to 
make it do more.

-James


On Tuesday, 6 November 2012 14:55:53 UTC-5, Charles Comstock wrote:
>
> I understand that, hence the example being to check if the value was a 
> function, since returning false from not'ing a function didn't make sense 
> to me. The change I was inquiring about applied to your example would be;
>
> (filter (fnot even?) [1 2 3 4 5 6 7]) => (1 3 5 7)
> (filter fnot [true false true]) => [false true false]
>
> So I fully understand that one is operating on values, and one is 
> operating on functions. What I was asking, is if it's ever useful to 
> execute not on a function but treat it as a value, just as it doesn't make 
> sense to execute complement on values instead of functions. Given that it 
> seemed the vast majority of use cases are distinct dependent on if you are 
> dealing with functions or values, I was questioning if the functions could 
> be combined to do the right thing depending on if it was a value or a 
> function. I was asking for arguments for and against that, but concluded it 
> was probably was due to complecting and was asking for verification.
>
> Thanks,
>
> Charlie
>
> On Tuesday, November 6, 2012 4:03:44 AM UTC-6, Stathis Sideris wrote:
>>
>> The difference between not and complement is that not takes a *value* and 
>> produces a new *value* which is true if the original was false (and vice 
>> versa) while complement takes a *function* and produces a new *function 
>> *which 
>> returns true in the cases where the original function would return false.
>>
>> Here is an example that shows how complement can result in more concise 
>> code in comparison to not:
>>
>> user> (filter (fn [x] (not (even? x))) [1 2 3 4 5 6 7])
>> (1 3 5 7)
>> user> (filter (complement even?) [1 2 3 4 5 6 7])
>> (1 3 5 7)
>>
>> (of course you could just use odd? in this case, but it's only an 
>> example).
>>
>> I hope that clears it up.
>>
>> Stathis
>>
>> On Monday, 5 November 2012 23:12:03 UTC, Charles Comstock wrote:
>>>
>>> Hi All,
>>>
>>> I quite like Clojure but have been confused from time to time on 
>>> particular design choices. I find understanding the root cause of these 
>>> decisions helps to understand the language better. As example, the fact 
>>> that complement and not are separate functions has been puzzling me for a 
>>> bit [1]. The implementation of not and complement is roughly;
>>>
>>> (defn not [x] (if x false true))
>>> (defn complement [f] 
>>>   (fn 
>>>  ([] (not (f)))
>>>  ([x] (not (f x)))
>>>  ([x y] (not (f x y)))
>>>  ([x y & zs] (not (apply f x y zs)
>>>
>>> What I'm wondering is if it's purely for performance, historical or 
>>> idiomatic reasons that it's not;
>>>
>>>
>>> (defn fnot [arg]
>>>   (if (ifn? arg)
>>> (fn
>>>   ([] (fnot (arg)))
>>>   ([x] (fnot (arg x)))
>>>   ([x y] (fnot (arg x y)))
>>>   ([x y & zs] (fnot (apply arg x y zs
>>> (if arg false true)))
>>>
>>> Perhaps a multi-method could also be appropriate here, though I'm not 
>>> exactly certain what the appropriate dispatch function would be. I follow 
>>> why bit-not is a separate function as the intended meaning is clearly 
>>> different, but the implied meaning of not seems to be the same as 
>>> complement which is why it seems odd that they are different methods. 
>>>
>>> After doing some experimentation with these, I finally realized that (not 
>>> identity) yields false, but I'm not quite following that use case. I'm 
>>> guessing the idiomatic argument against fnot is that it would complect not 
>>> and complement unnecessarily?
>>>
>>> While pouring through the clojure.core source, I also saw a few functions 
>>> like not-every? which use (comp not every?) instead of (complement every?). 
>>> This led me to question why complement is not implemented as;
>>>
>>>
>>> (defn complement [f] (comp not f))
>>>
>>>
>>> Is there a difference that I'm just not seeing? Or is that just a side 
>>> effect of either performance or dependency ordering in clojure.core [2].
>>>
>>> I think I may have answered my own question concerning fnot in a roundabout 
>>> manner, but I found the process of discovering this illuminating. Can 
>>> anyone else shed light on this, or am I correct in concluding that fnot 
>>> would complect not and complement?
>>>
>>> Thanks,
>>>  Charlie
>>>
>>> 1. I frequently misread comp as complement and not compose in point free 
>>> code, so perhaps that confusion is why complement is oddly jarring to me.
>>>
>>> 2. not-every? and not-any? are implemented using def instead of defn and 
>>> manually set meta :arglist, despite defn already being defined, is this 
>>> just for historical reasons?
>>>
>>>
>>>

-- 
You received this message because you are subscribed to the Google
Groups "Cloju

Re: Clojure web framework

2012-10-01 Thread James MacAulay
Frameworks have benefits which can't easily be achieved with documentation. 
The most obvious to me is that a framework lets you fire up a complete 
system of carefully curated components in no time. They also let you defer 
choices until you actually need to care about them.

Because Clojure's libraries are so composable, it seems like a good 
approach to fill this gap would be "just" a lein project template with an 
opinionated set of dependencies, a sane and predictable folder hierarchy, 
and a good Getting Started Guide. A quick clojars search reveals many that 
might fit that description, but none have very high visibility.

-James

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