Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Hi,

I just read a blog post [1] talking about Elixir pattern matching. I was 
thoroughly impressed with the way its handled in Elixir. I am posting this 
here cuz I got rather excited and wanted to discuss this with you all. 

My experience with pattern matching is limited to the basics of F# and 
reading the docs of core.match. I think its a great idea, but I also feel 
unless its supported by language at the fundamental level, it remains as 
syntactic sugar. 

All pattern matching code I had read previously, involve matching on a 
specific argument, often inside a function. From what I see in the blog 
post, in Elixir its taken one step further and pattern matching is done at 
the function declaration/invocation level. Normally one would create one 
outer public function and multiple private (?) functions to handle each 
branch. The outer function would only have the pattern matching code. At 
the very least, I find the Elixir version easier to read. It seems to be 
idiomatic for Elixir libraries, functions to return a tuple whose first 
(few?) elements are purely used for pattern matching. 

Consider the following code samples from that blog post,

def to_registration_result({:ok, res}) do
  {:ok, %Membership.RegistrationResult{
success: res["success"],
message: res["message"],
new_id: res["new_id"],
validation_token: res["validation_token"],
authentication_token: res["authentication_token"]
  }}
end

def to_registration_result({:error, err}) do
  {:error, err}
end

Normally, I would have one function with an if condition to check for an 
error value in the args and then call respective functions to handle each 
branch. I could also do

(defmulti to-registration-result first)

(defmethod to-registration-result :ok
  [[_ email password]]
  (println email password))

(defmethod to-registration-result :err
  [[_ err]]
  (println "err: " err))

But this wouldn't be idiomatic Clojure. This would also require all 
libraries and functions to return data in a certain form, one where in the 
first element is some kind of status. 

He has another example where pattern matching is used with recursive 
functions to handle transition from one state/step to another and handle 
terminating conditions. This specific example is a very poor choice, but it 
does demonstrate the possibilities.

def map_single({:ok, res}) do
  cols = res.columns
  [first_row | _] = res.rows
  map_single {:cols_and_first, cols, first_row}
end

def map_single({:cols_and_first, cols, first_row}) do
  zipped = List.zip([cols,first_row])
  map_single {:zipped, zipped}
end

def map_single({:zipped, list}) do
  {:ok, Enum.into(list, %{})}
end

def map_single({:error, err}) do
  {:error, err}
end

Interesting stuff. 

[1] - 
http://rob.conery.io/2015/09/04/using-recursion-in-elixir-to-break-your-oo-brain/

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread James Reeves
You might want to take a look at defun: https://github.com/killme2008/defun

- James

On 5 September 2015 at 09:24, Amith George  wrote:

> Hi,
>
> I just read a blog post [1] talking about Elixir pattern matching. I was
> thoroughly impressed with the way its handled in Elixir. I am posting this
> here cuz I got rather excited and wanted to discuss this with you all.
>
> My experience with pattern matching is limited to the basics of F# and
> reading the docs of core.match. I think its a great idea, but I also feel
> unless its supported by language at the fundamental level, it remains as
> syntactic sugar.
>
> All pattern matching code I had read previously, involve matching on a
> specific argument, often inside a function. From what I see in the blog
> post, in Elixir its taken one step further and pattern matching is done at
> the function declaration/invocation level. Normally one would create one
> outer public function and multiple private (?) functions to handle each
> branch. The outer function would only have the pattern matching code. At
> the very least, I find the Elixir version easier to read. It seems to be
> idiomatic for Elixir libraries, functions to return a tuple whose first
> (few?) elements are purely used for pattern matching.
>
> Consider the following code samples from that blog post,
>
> def to_registration_result({:ok, res}) do
>   {:ok, %Membership.RegistrationResult{
> success: res["success"],
> message: res["message"],
> new_id: res["new_id"],
> validation_token: res["validation_token"],
> authentication_token: res["authentication_token"]
>   }}
> end
>
> def to_registration_result({:error, err}) do
>   {:error, err}
> end
>
> Normally, I would have one function with an if condition to check for an
> error value in the args and then call respective functions to handle each
> branch. I could also do
>
> (defmulti to-registration-result first)
>
> (defmethod to-registration-result :ok
>   [[_ email password]]
>   (println email password))
>
> (defmethod to-registration-result :err
>   [[_ err]]
>   (println "err: " err))
>
> But this wouldn't be idiomatic Clojure. This would also require all
> libraries and functions to return data in a certain form, one where in the
> first element is some kind of status.
>
> He has another example where pattern matching is used with recursive
> functions to handle transition from one state/step to another and handle
> terminating conditions. This specific example is a very poor choice, but it
> does demonstrate the possibilities.
>
> def map_single({:ok, res}) do
>   cols = res.columns
>   [first_row | _] = res.rows
>   map_single {:cols_and_first, cols, first_row}
> end
>
> def map_single({:cols_and_first, cols, first_row}) do
>   zipped = List.zip([cols,first_row])
>   map_single {:zipped, zipped}
> end
>
> def map_single({:zipped, list}) do
>   {:ok, Enum.into(list, %{})}
> end
>
> def map_single({:error, err}) do
>   {:error, err}
> end
>
> Interesting stuff.
>
> [1] -
> http://rob.conery.io/2015/09/04/using-recursion-in-elixir-to-break-your-oo-brain/
>
> --
> 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.
>

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


[ANN] descjop 0.3.0 Om based app supprt.

2015-09-05 Thread Kazuhiro Hara
descjop v0.3.0 (https://github.com/karad/lein_template_descjop)
has just been released today!

descjop is a Leiningen template for Web based desktop
application with Electron.

Features:

- add option for Om based desctop application.


you can try add "+om" option.

```
$ lein new descjop YOUR_APP_NAME +om
```

# descjop
https://github.com/karad/lein_template_descjop
https://clojars.org/descjop/lein-template


-- 
--


-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Nice. Hadn't heard of it before. It looks interesting. The criterium 
benchmark is kinda disappointing though. The pattern matched function took 
nearly 15x the time of the normal function.

Performance aside, in Elixir, there seems to be an established convention 
for creating the function argument tuple. Every function can expect to be 
pattern matched against both :ok and :err. NodeJS callbacks also have 
follow a convention, error first, which would make it trivial to pattern 
match against. Goodbye to all those mundane `if (err) {} else {}` checks. I 
can't quite think of any similar conventions in Clojure. 



On Saturday, 5 September 2015 14:05:02 UTC+5:30, James Reeves wrote:
>
> You might want to take a look at defun: 
> https://github.com/killme2008/defun
>
> - 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.


[ANN] clasew 0.2.0 - Clojure Applescript Execution Wrapper

2015-09-05 Thread Frank Castellucci
https://github.com/FrankC01/clasew

*clasew *- Clojure AppleScriptEngine Wrapper

*Intent* - clasew provides an idiomatic Clojure wrapper for Java 
ScriptManager: specifically apple.AppleScriptManager, as well as providing 
scriptable applications HOF DSLs.
Realizing that the audience for such capability may be minimal, others may 
find this a useful addition to the 'niche' library. 

*General changes in 0.2.0*

   - Added support for Apple's Contacts and Microsoft Outlook identities 
   (identities.clj)
   - Using experimental AST generation and Applescript emitter
   

*Changes* - All changes details: 
https://github.com/FrankC01/clasew/blob/master/CHANGES.md

Feedback (+/-) and comments (+/-) are always welcome and appreciated.

Enjoy
Frank V. Castellucci

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Gary Verhaegen
It won't really help for the library/ecosystem problem, but for your own
code I'd recommend watching Jeanine Atkinson's Conj talk from last year:

http://m.youtube.com/watch?v=ZQkIWWTygio

On Saturday, 5 September 2015, Amith George  wrote:

> Nice. Hadn't heard of it before. It looks interesting. The criterium
> benchmark is kinda disappointing though. The pattern matched function took
> nearly 15x the time of the normal function.
>
> Performance aside, in Elixir, there seems to be an established convention
> for creating the function argument tuple. Every function can expect to be
> pattern matched against both :ok and :err. NodeJS callbacks also have
> follow a convention, error first, which would make it trivial to pattern
> match against. Goodbye to all those mundane `if (err) {} else {}` checks. I
> can't quite think of any similar conventions in Clojure.
>
>
>
> On Saturday, 5 September 2015 14:05:02 UTC+5:30, James Reeves wrote:
>>
>> You might want to take a look at defun:
>> https://github.com/killme2008/defun
>>
>> - 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.
>

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


AATree release 0.1.0, an indexed sorted map

2015-09-05 Thread William la Forge
Release 0.1.0 provides an alternative to sorted-map, though it also 
implements the Indexed interface.
Written entirely in Clojure, subclassing APersistentMap and validated with 
collection-check .

https://github.com/laforge49/aatree

As a newbie I would very much appreciate any feedback. Thanks!

-- 
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: supporting metadata caret reader syntax with deftype

2015-09-05 Thread Artur Malabarba
I had the same issue a couple of months ago. The thing to understand
is that 'a is NOT a symbol. Actually, it evaluates to a symbol, which
is a different thing.

When you write ^{:a 1} 'a, it is the same as writing ^{:a 1} (quote
a). So the metadata gets applied to the entire form, not the symbol.
When you write '^{:a 1} a, it is the same as writing (quote ^{:a 1}
a). So the metadata gets applied to the symbol.

-- 
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: supporting metadata caret reader syntax with deftype

2015-09-05 Thread Mike Rodriguez
I think Artur described it well. I don't think the docs are wrong. The thing is 
just understanding that the reader macro syntax is interpreted by the reader. 
The reader comes before the evaluation of the compiler (there is grey area here 
with read-eval but that's another topic). 

Since a symbol is auto-resolved by the compiler during eval you have to quote 
them if you want to prevent that. Due to that it makes using a reader macro 
with a symbol awkward, but it makes sense if you think about it. The reader 
macro must apply to the symbol literal form itself. Then you surround the 
returned symbol with quote to prevent the compiler from resolving through it 
post-reading. Putting the metadata outside the quote is just attaching it to a 
list for, from the readers perspective. It doesn't know it is a quote etc. 

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Rob Lally
Out of interest, I ran the benchmarks as is, and got more or less the same 
results - 15x. Then I tried upgrading the defun dependencies - clojure, 
core.match and tools.macro - all of which have newer versions, and then running 
the benchmarks without leiningen’s jvm-opts and in a trampolined repl. The 
results are better (see below). Still not great - but down from 15x to 10x. 

That said:

* I’m not sure I’d care: for most applications the overhead of function 
dispatch is probably not the bottleneck.
* Elixir and the BEAM VM are awesome at many things, but I suspect (from 
experience not evidence) that the defun version is still faster than the elixir 
version.


Rob

---

user=> (bench (accum-defn 1))
WARNING: Final GC required 2.590098761776679 % of runtime
Evaluation count : 429360 in 60 samples of 7156 calls.
 Execution time mean : 139.664539 µs
Execution time std-deviation : 4.701755 µs
   Execution time lower quantile : 134.451108 µs ( 2.5%)
   Execution time upper quantile : 150.214646 µs (97.5%)
   Overhead used : 1.565276 ns

Found 5 outliers in 60 samples (8. %)
low-severe   5 (8. %)
 Variance from outliers : 20.5880 % Variance is moderately inflated by outliers

user=> (bench (accum-defun 1))
Evaluation count : 44940 in 60 samples of 749 calls.
 Execution time mean : 1.361631 ms
Execution time std-deviation : 40.489537 µs
   Execution time lower quantile : 1.333474 ms ( 2.5%)
   Execution time upper quantile : 1.465123 ms (97.5%)
   Overhead used : 1.565276 ns

Found 9 outliers in 60 samples (15. %)
low-severe   1 (1.6667 %)
low-mild 8 (13. %)
 Variance from outliers : 17.3434 % Variance is moderately inflated by outliers

---


> On 5 Sep 2015, at 05:16, Amith George  wrote:
> 
> Nice. Hadn't heard of it before. It looks interesting. The criterium 
> benchmark is kinda disappointing though. The pattern matched function took 
> nearly 15x the time of the normal function.

-- 
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: midje only 1 test

2015-09-05 Thread Brian Marick
I *strongly* recommend doing all your testing in a repl buffer. That 
given, there are two ways to solve your problem. The first, which I 
prefer, is to start by testing everything:


(use 'midje.repl)
(autotest)

Then, when you change any text and save the namespace it's in, all tests 
that depend on that namespace will be rerun, including the one you're 
specifically working on.


The other alternative is to rerun your specific test with something like:

(check-facts #"fact description")

... or, once you've run a specific fact:

(recheck-fact)



r/ Wobben wrote:

hello,

Suppose I have this test

(facts "do-a-thing" {:exercise 1  :points 1}  (do-a-thing 3) =>
46656.0 (do-a-thing 1) => 4.0(do-a-thing 0) => 1.0)


Is there a way I can only run this test
I tried lein midje :filter exercise 1
but that one fails.

Roelof

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


--
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
Thanks, it helps to know using a tagged vector is a real pattern :) Gives 
the confidence to explore this further for my own code. 

On Saturday, 5 September 2015 22:37:33 UTC+5:30, Gary Verhaegen wrote:
>
> It won't really help for the library/ecosystem problem, but for your own 
> code I'd recommend watching Jeanine Atkinson's Conj talk from last year:
>
> http://m.youtube.com/watch?v=ZQkIWWTygio
>
>>
>>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George

>
> * Elixir and the BEAM VM are awesome at many things, but I suspect (from 
> experience not evidence) that the defun version is still faster than the 
> elixir version.


In Clojure, the defun version is not the default or idiomatic way to write 
functions. I kind of expected it to be slower. Maybe if the core team felt 
it was good enough to be the default, they could make internal changes to 
the core to optimize stuff (pure speculation here). 

On the other hand, skimming through the elixir documentation gives me the 
feeling that pattern matched functions is the default way to write. As a 
first class language feature, I find it hard to believe it is slower 
(compared to what in Elixir?).   Or do you mean the Beam VM in general is 
slower than the JVM? 

On Sunday, 6 September 2015 02:04:17 UTC+5:30, Rob Lally wrote:
>
> Out of interest, I ran the benchmarks as is, and got more or less the same 
> results - 15x. Then I tried upgrading the defun dependencies - clojure, 
> core.match and tools.macro - all of which have newer versions, and then 
> running the benchmarks without leiningen’s jvm-opts and in a trampolined 
> repl. The results are better (see below). Still not great - but down from 
> 15x to 10x. 
>
> That said:
>
> * I’m not sure I’d care: for most applications the overhead of function 
> dispatch is probably not the bottleneck.
> * Elixir and the BEAM VM are awesome at many things, but I suspect (from 
> experience not evidence) that the defun version is still faster than the 
> elixir version.
>
>
> Rob
>
> ---
>
> user=> (bench (accum-defn 1))
> WARNING: Final GC required 2.590098761776679 % of runtime
> Evaluation count : 429360 in 60 samples of 7156 calls.
>  Execution time mean : 139.664539 µs
> Execution time std-deviation : 4.701755 µs
>Execution time lower quantile : 134.451108 µs ( 2.5%)
>Execution time upper quantile : 150.214646 µs (97.5%)
>Overhead used : 1.565276 ns
>
> Found 5 outliers in 60 samples (8. %)
> low-severe   5 (8. %)
>  Variance from outliers : 20.5880 % Variance is moderately inflated by 
> outliers
>
> user=> (bench (accum-defun 1))
> Evaluation count : 44940 in 60 samples of 749 calls.
>  Execution time mean : 1.361631 ms
> Execution time std-deviation : 40.489537 µs
>Execution time lower quantile : 1.333474 ms ( 2.5%)
>Execution time upper quantile : 1.465123 ms (97.5%)
>Overhead used : 1.565276 ns
>
> Found 9 outliers in 60 samples (15. %)
> low-severe   1 (1.6667 %)
> low-mild 8 (13. %)
>  Variance from outliers : 17.3434 % Variance is moderately inflated by 
> outliers
>
> ---
>
>
> On 5 Sep 2015, at 05:16, Amith George > 
> wrote:
>
> Nice. Hadn't heard of it before. It looks interesting. The criterium 
> benchmark is kinda disappointing though. The pattern matched function took 
> nearly 15x the time of the normal function.
>
>
>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Timothy Baldridge
>> Thanks, it helps to know using a tagged vector is a real pattern :)

I don't know that it's a "real pattern". If I saw code like this in
production I would probably raise quite a stink about it during code
reviews. It's a cute hack, but it is also an abuse of a data structure. Now
when I see [:foo 42] I don't know if I have a vector of data or a tagged
value. It's a better idea IMO to use something like deftype or defrecord to
communicate the type of something. I'd much rather see #foo.bar.Age{:val
42} than [:foo.bar/age 42]. At least then when I do (type val) I don't get
clojure.lang.PersistentVector.

Timothy

On Sat, Sep 5, 2015 at 4:55 PM, Amith George  wrote:

> * Elixir and the BEAM VM are awesome at many things, but I suspect (from
>> experience not evidence) that the defun version is still faster than the
>> elixir version.
>
>
> In Clojure, the defun version is not the default or idiomatic way to write
> functions. I kind of expected it to be slower. Maybe if the core team felt
> it was good enough to be the default, they could make internal changes to
> the core to optimize stuff (pure speculation here).
>
> On the other hand, skimming through the elixir documentation gives me the
> feeling that pattern matched functions is the default way to write. As a
> first class language feature, I find it hard to believe it is slower
> (compared to what in Elixir?).   Or do you mean the Beam VM in general is
> slower than the JVM?
>
> On Sunday, 6 September 2015 02:04:17 UTC+5:30, Rob Lally wrote:
>
>> Out of interest, I ran the benchmarks as is, and got more or less the
>> same results - 15x. Then I tried upgrading the defun dependencies -
>> clojure, core.match and tools.macro - all of which have newer versions, and
>> then running the benchmarks without leiningen’s jvm-opts and in a
>> trampolined repl. The results are better (see below). Still not great - but
>> down from 15x to 10x.
>>
>> That said:
>>
>> * I’m not sure I’d care: for most applications the overhead of function
>> dispatch is probably not the bottleneck.
>> * Elixir and the BEAM VM are awesome at many things, but I suspect (from
>> experience not evidence) that the defun version is still faster than the
>> elixir version.
>>
>>
>> Rob
>>
>> ---
>>
>> user=> (bench (accum-defn 1))
>> WARNING: Final GC required 2.590098761776679 % of runtime
>> Evaluation count : 429360 in 60 samples of 7156 calls.
>>  Execution time mean : 139.664539 µs
>> Execution time std-deviation : 4.701755 µs
>>Execution time lower quantile : 134.451108 µs ( 2.5%)
>>Execution time upper quantile : 150.214646 µs (97.5%)
>>Overhead used : 1.565276 ns
>>
>> Found 5 outliers in 60 samples (8. %)
>> low-severe   5 (8. %)
>>  Variance from outliers : 20.5880 % Variance is moderately inflated by
>> outliers
>>
>> user=> (bench (accum-defun 1))
>> Evaluation count : 44940 in 60 samples of 749 calls.
>>  Execution time mean : 1.361631 ms
>> Execution time std-deviation : 40.489537 µs
>>Execution time lower quantile : 1.333474 ms ( 2.5%)
>>Execution time upper quantile : 1.465123 ms (97.5%)
>>Overhead used : 1.565276 ns
>>
>> Found 9 outliers in 60 samples (15. %)
>> low-severe   1 (1.6667 %)
>> low-mild 8 (13. %)
>>  Variance from outliers : 17.3434 % Variance is moderately inflated by
>> outliers
>>
>> ---
>>
>>
>> On 5 Sep 2015, at 05:16, Amith George  wrote:
>>
>> Nice. Hadn't heard of it before. It looks interesting. The criterium
>> benchmark is kinda disappointing though. The pattern matched function took
>> nearly 15x the time of the normal function.
>>
>>
>> --
> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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

Re: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
In Elixir, tuples are used where in the first element is the tag. A similar 
thing can be done in Clojure using vectors. That much was clear. What 
bothered me and prompted me to start this thread was I wasn't sure "what" 
it is I was doing by creating that vector. Was it purely a convention 
thing? What did the convention mean? It looked weird. 

The "aha" moment for me came while watching her talk. The tagged vector is 
simply a way to represent one case of an open discriminated union. 
Discriminated unions are a common approach in a language like F#. A 
function could return an union type Result, with cases Success and Error. 
And it gels very nicely with pattern matching. 

In that light, I can acknowledge tagged vectors as a real pattern. Creating 
records for all these cases wouldn't be worth it in my opinion. Infact one 
would usually just return a map of values. The caller would branch 
depending on the presence of an `:err` key. Each branch would have access 
to the entire map and its not evident which keys are branch specific. The 
pattern matching approach on the other hand makes explicit the values for 
each branch. 

On Sunday, 6 September 2015 07:01:40 UTC+5:30, tbc++ wrote:
>
> >> Thanks, it helps to know using a tagged vector is a real pattern :) 
>
> I don't know that it's a "real pattern". If I saw code like this in 
> production I would probably raise quite a stink about it during code 
> reviews. It's a cute hack, but it is also an abuse of a data structure. Now 
> when I see [:foo 42] I don't know if I have a vector of data or a tagged 
> value. It's a better idea IMO to use something like deftype or defrecord to 
> communicate the type of something. I'd much rather see #foo.bar.Age{:val 
> 42} than [:foo.bar/age 42]. At least then when I do (type val) I don't get 
> clojure.lang.PersistentVector.
>
> Timothy
>
>

-- 
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: Just found out about Elixirs function argument pattern matching...

2015-09-05 Thread Amith George
defun, core.match, tagged vectors - seems like I can emulate Elixir 
function pattern match behaviour. I took some simple code I found online 
(https://twitter.com/Xzilend/status/640282621042233344) and rewrote it to 
1) use only tagged vectors (not quite) and 2) use defun and tagged vectors. 
I am eager to hear your thoughts on the rewrite.

Original 
(defn- register
  [db mailer email password]
  (if (users/valid? email password)
(if (users/taken? db email)
  (response/bad-request {:errors [{:message "That email is taken."}]})
  (do (users/do-create! db email password)
  (users/notify mailer email activate-subject activate-text)
  (response/ok (auth/authenticate email
(response/bad-request {:errors [{:message errors/invalid-creds}]})))

Lets ignore the possible concurrency issues for now.

Rewrite without using core.match

(defn register
  ([db mailer email password]
   (register [:start {:db db :mailer mailer :email email :password password
}]))
  ([status {:keys [db mailer email password] :as args}]
   (cond 
 (= status :start) 
 (if (users/valid? email password) 
   (register [:check-unique args])
   (register [:err {:res "Invalid credentials"}]))

 (= status :check-unique)
 (if (users/taken? db email)
   (register [:create args])
   (register [:err {:res "User already exisits"}]))

 (= status :create)
 (do (users/do-create! db email password)
 (users/notify mailer email activate-subject activate-text)
 (register [:ok {:res (auth/authenticate email)}]))

 (= status :ok) (response/ok (:res args))

 (= status :err) (response/bad-request {:errors [{:message (:res args
)}]}


With no pattern matching I had to wrap the actual arguments into a map so 
that all recursive calls hit the two argument arity. 

Using defun and tagged vectors,

(defn register [& args] (register' (into [:start] args)))

(defun- register'
  ([:start db mailer email password] 
   (if (users/valid? email password) 
 (register' [:check-unique db mailer email password])
 (register' [:err "Invalid credentials"])))
  ([:check-unique db mailer email password]
   (if (users/taken? db email)
 (register' [:create db mailer email password])
 (register' [:err "User already exists"])))
  ([:create db mailer email password]
   (do (users/do-create! db email password)
   (users/notify mailer email activate-subject activate-text)
   (register' [:ok (auth/authenticate email)])))
  ([:ok res] (response/ok (:res args)))
  ([:err msg] (response/bad-request {:errors [{:message (:res args)}]})))

I couldn't find a way to refer to the arguments vector from within the body 
of a case. I would have preferred writing the :start case like this,

  ([:start _ _ email password] 
   (if (users/valid? email password) 
 (register' (into [:check-unique] it)
 (register' [:err "Invalid credentials"])))



I find the defun version better compared to the plain if else version. Step 
transitions are explicit. Early exit is a transition to err state. The 
`response/bad-request` call occurs only once as opposed to at each early 
exit point. 

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