Re: Tour of our 250k line Clojure codebase

2021-06-09 Thread Timothy Baldridge
On Wed, Jun 9, 2021 at 6:14 PM Nathan Marz  wrote:

> Continuations in our language are expressed very differently than has
> existed before (e.g. like in Scheme). They fit intuitively within the
> overall paradigm our language implements. Far from being complex or hard to
> comprehend, continuations are the key construct that enables us to avoid
> mountains of complexity that exist otherwise in distributed systems. I know
> this from personal experience building distributed systems in the past. The
> degree to which continuations help write asynchronous, reactive, and
> parallel code is huge. It would be clear if you saw the language in action,
> but we're keeping it under wraps for now.
>

Could you expound on that for those of us who are familiar with
continuations in many forms, and languages? While delimited, multi-prompt,
multi-shot continuations are certainly helpful in reducing complexity
compared to traditional full continuations, they still result in spaghetti
code unless coupled with some sort of typing and/or algebraic effect
system. Most research in this space shows some promise, so I’m interested
in seeing how you’ve solved the many well documented problems with these
approaches.

-- 
“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.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CAL36E%2Bv-a8P9wMEot2XspTk0GKiqk3EPCpTrqpK1FBesnFB9hg%40mail.gmail.com.


[JOB] [US/CA/Fully Remote] Cisco is looking for a Clojure / Distributed Systems Programmer

2021-04-26 Thread Timothy Baldridge
Cisco is looking for a Clojure developer to join our malware analysis
group: Threat Grid. We manage data produced by dynamic analysis of
malware and provide a wide variety of REST services to our clients.
Seeing as we deal with around 700k samples a day, and maintain a
dataset of 400TB, we are never short of interesting problems.

Location: Canada/US, 100% remote, team is 100% distributed
What we are looking for: Advanced Clojure experience or distributed
systems (preferably both)
Compensation: Competitive salary and benefits, yearly bonus, RSUs

In 2020 Cisco was named #1 on the World’s Best Workplaces list by
Great Places to Work and Fortune Magazine for the second year in a
row! The Threat Grid project at Cisco has an excellent balance of the
agility of a startup combined with the resources of a large
corporation.

More information : https://jobs.cisco.com/jobs/ProjectDetail/1322623

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/CAL36E%2Btv8c4YcfDoO24W7OWb6gap97ti24m%3DgsTByPzVBo0X7g%40mail.gmail.com.


[Job] Cisco Malware Analytics (ThreatGrid) - Remote US

2021-03-15 Thread Timothy Baldridge


My team at Cisco is looking to hire another Clojure developer. The official 
job description can be found on the Cisco site 
https://jobs.cisco.com/jobs/ProjectDetail/1322623 .

We are part of the Cisco Secure Malware Analytics (Threat Grid) team, where 
we write software to analyze and categorize malware. We maintain roughly 
400TB of ElasticSearch data and 1-2 TB of SQL data, so a lot of our 
problems are in that fun space of distributed systems, and "big data".

Feel free to ask questions here, apply via the link above, or email me.

Timothy Baldridge

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/99a53336-21e2-42e6-9b1e-e7deb0bcb56cn%40googlegroups.com.


Re: [ANN] Clojure 1.10.0-beta8

2018-11-21 Thread Timothy Baldridge
For sure, but some documentation of that process would be nice, otherwise
the “nah, were good” replies come off as condescending.

I’ve typed up a few other comments, and then deleted them, as they’re
getting too OT. So I’ll exit the conversation, and unsub from this mailing
list, since it’s clear outside input isn’t valued, aside from being
crowdsourced QA.




On Wed, Nov 21, 2018 at 12:40 PM Andy Fingerhut 
wrote:

> I suspect Alex and other folks have already done all of the bikeshedding
> internally that they have the patience for, and are content with the name
> and the reasons they ahve for it, and are not enthusiastic about another
> round of that in a public forum.
>
> Rich owns Clojure code legally, and I would say ethically as well (given
> his time investment vs. that of others in it, and his original authorship
> of most of the code, and that everyone who contributed code agreed in
> advance to give him co-ownership).  Project maintainers get to craft the
> rules by which changes are made, for any project.  Some choose to turn it
> over to a committee, others do not.
>
> Andy
>
>
> On Wed, Nov 21, 2018 at 11:25 AM Timothy Baldridge 
> wrote:
>
>> >>   We’re good with the name. The docstring exists for further
>> explanation.
>>
>> Except the code is less-readable. The name is meaningless.
>> "async-require" appends the adverb "async" to the verb "require", therefore
>> making it an asynchronous variant of require, which is exactly the opposite
>> of what the function actually does. So it might as well be named
>> `foo-require`. Actually `foo-require` is better, since I don't know what
>> `foo` means and I'd look up the docstring to find out. With `async-requrie`
>> I now have more cognitive load having to remember what Clojure's special
>> definition of `async` is in this context. All these crazy edge-cases in the
>> naming of the language really start to add up after awhile, and it takes
>> mental space away that I could be using to focus on the problem I'm trying
>> to solve.
>>
>> It blows my mind that the Clojure team even cares enough to say no to
>> this, why does it matter this much that it can't change. This conversation
>> reinforces the view that Clojure is close-source development. Once the
>> community hears about a feature, it's written in stone. Apparently all
>> required input has already been thought of and anything the community says
>> couldn't possibly matter.
>>
>>
>>
>> On Wed, Nov 21, 2018 at 11:34 AM Chris Nuernberger 
>> wrote:
>>
>>> Agreed, specifically to avoid things like this:
>>>
>>> https://github.com/tech-ascent/tech.compute/blob/master/src/tech/compute/cpu/tensor_math.clj#L45
>>>
>>> Great timing and we will be looking forward to it!
>>>
>>> On Wed, Nov 21, 2018 at 11:09 AM Sean Corfield 
>>> wrote:
>>>
>>>> This makes me smile… My first reaction to the name was the same as
>>>> Alexander’s and then my second reaction cut in: “No, they’ll have thought
>>>> about the name and won’t entertain changes” 
>>>>
>>>>
>>>>
>>>> It’s for safely doing requires in asynchronous (multi-threaded) code.
>>>>
>>>>
>>>>
>>>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
>>>> An Architect's View -- http://corfield.org/
>>>>
>>>> "If you're not annoying somebody, you're not really alive."
>>>> -- Margaret Atwood
>>>>
>>>>
>>>> --
>>>> *From:* clojure@googlegroups.com  on behalf
>>>> of Alex Miller 
>>>> *Sent:* Wednesday, November 21, 2018 9:54:28 AM
>>>> *To:* clojure@googlegroups.com
>>>> *Subject:* Re: [ANN] Clojure 1.10.0-beta8
>>>>
>>>> We’re good with the name. The docstring exists for further explanation.
>>>>
>>>> On Nov 21, 2018, at 11:29 AM, Alexander Yakushev 
>>>> wrote:
>>>>
>>>> Could I suggest bikeshedding on the name async-require? Before I've
>>>> seen the patch, my initial impression was that it loads namespaces
>>>> asynchronously (that is, returns control immediately and loads them in the
>>>> background). It might be somewhat confusing that a function
>>>> async-require is actually even more synchronous than the regular
>>>> require :). How about synchronized-require (it's basically
>>>> word-to-word description of the function body)?
>>>>
>>>&

Re: [ANN] Clojure 1.10.0-beta8

2018-11-21 Thread Timothy Baldridge
>>   We’re good with the name. The docstring exists for further
explanation.

Except the code is less-readable. The name is meaningless. "async-require"
appends the adverb "async" to the verb "require", therefore making it an
asynchronous variant of require, which is exactly the opposite of what the
function actually does. So it might as well be named `foo-require`.
Actually `foo-require` is better, since I don't know what `foo` means and
I'd look up the docstring to find out. With `async-requrie` I now have more
cognitive load having to remember what Clojure's special definition of
`async` is in this context. All these crazy edge-cases in the naming of the
language really start to add up after awhile, and it takes mental space
away that I could be using to focus on the problem I'm trying to solve.

It blows my mind that the Clojure team even cares enough to say no to this,
why does it matter this much that it can't change. This conversation
reinforces the view that Clojure is close-source development. Once the
community hears about a feature, it's written in stone. Apparently all
required input has already been thought of and anything the community says
couldn't possibly matter.



On Wed, Nov 21, 2018 at 11:34 AM Chris Nuernberger 
wrote:

> Agreed, specifically to avoid things like this:
>
> https://github.com/tech-ascent/tech.compute/blob/master/src/tech/compute/cpu/tensor_math.clj#L45
>
> Great timing and we will be looking forward to it!
>
> On Wed, Nov 21, 2018 at 11:09 AM Sean Corfield  wrote:
>
>> This makes me smile… My first reaction to the name was the same as
>> Alexander’s and then my second reaction cut in: “No, they’ll have thought
>> about the name and won’t entertain changes” 
>>
>>
>>
>> It’s for safely doing requires in asynchronous (multi-threaded) code.
>>
>>
>>
>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>>
>> "If you're not annoying somebody, you're not really alive."
>> -- Margaret Atwood
>>
>>
>> --
>> *From:* clojure@googlegroups.com  on behalf of
>> Alex Miller 
>> *Sent:* Wednesday, November 21, 2018 9:54:28 AM
>> *To:* clojure@googlegroups.com
>> *Subject:* Re: [ANN] Clojure 1.10.0-beta8
>>
>> We’re good with the name. The docstring exists for further explanation.
>>
>> On Nov 21, 2018, at 11:29 AM, Alexander Yakushev 
>> wrote:
>>
>> Could I suggest bikeshedding on the name async-require? Before I've seen
>> the patch, my initial impression was that it loads namespaces
>> asynchronously (that is, returns control immediately and loads them in the
>> background). It might be somewhat confusing that a function async-require
>> is actually even more synchronous than the regular require :). How about 
>> synchronized-require
>> (it's basically word-to-word description of the function body)?
>>
>> Otherwise, thanks for this one, I needed something like this plenty of
>> times!
>>
>> On Wednesday, November 21, 2018 at 5:17:26 PM UTC+2, Alex Miller wrote:
>>>
>>> 1.10.0-beta8 is now available.
>>>
>>> You can try it with clj using:
>>>
>>> clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta8"}}}'
>>>
>>> Changes in 1.10.0-beta8:
>>>
>>>- CLJ-2438  - demunge
>>>source location in execution error messages
>>>- CLJ-2437  - add
>>>async-require and use it from requiring-resolve
>>>- CLJ-2436  - fix
>>>reflection warning in reflect.java
>>>
>>> You can read the full 1.10 changelog here:
>>> https://github.com/clojure/clojure/blob/master/changes.md
>>>
>> --
>> 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 a topic in the
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/clojure/2GQQpxNcDlM/unsubscribe.
>> To unsubscribe from this group and all its topics, 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 

Re: [ANN] 1.10.0-beta5

2018-11-08 Thread Timothy Baldridge
Nope, you're right, I missed the "extend, extend-type, extend-protocol"
part of the original post.

On Thu, Nov 8, 2018 at 10:12 AM Alex Miller  wrote:

>
> On Thursday, November 8, 2018 at 10:44:34 AM UTC-6, tbc++ wrote:
>>
>> The instance based polymorphism is a bit wonky in some cases. Can we get
>> some sort of spec that tells us what the rules are for resolution?
>>
>
> From the top of the thread: "Protocol implementations are checked first
> for direct definitions (defrecord, deftype, reify), then metadata
> definitions, then external extensions (extend, extend-type,
> extend-protocol)."  Was that unclear in some way? I think it explains
> everything you're seeing.
>
> We do plan to update the protocols reference page for final release, but
> waiting on that.
>
> We are still doing performance eval on this too - still might change a bit
> more.
>
>
>
>
>> See these cases where it breaks in some rather strange ways.
>>
>> Clojure 1.10.0-beta5
>> user=> (defprotocol ILevel (level [this]))
>> ILevel
>> user=> (extend-protocol ILevel
>>  clojure.lang.IPersistentVector
>>  (level [this] "interface"))
>> nil
>> user=> (extend-protocol ILevel
>>  Object
>>  (level [this] "object"))
>> nil
>> user=> (level [])
>> "interface"
>> user=> (level :key)
>> "object"
>> user=> (level (with-meta 'foo {`level (fn [this] "instance")}))
>> "instance"
>> user=> (level (with-meta [] {`level (fn [this] "instance")}))
>> "instance"
>> user=> (defrecord MyType [] ILevel (level [this] "type"))
>> user.MyType
>> ;; Fails to override
>> user=> (level (with-meta (->MyType) {`level (fn [this] "instance")}))
>> "type"
>> user=> (defrecord MyType3 [])
>> user.MyType3
>> user=> (extend-protocol ILevel
>>  MyType3
>>  (level [this] "type"))
>> nil
>> user=> (level (->MyType3))
>> "type"
>> ;; Overrides
>> user=> (level (with-meta (->MyType3) {`level (fn [this] "instance")}))
>> "instance"
>> user=>
>>
>> So it looks like if someone uses inline protocol extension that class
>> cannot participate in instance level polymorphism. If however they use
>> extend on the type after it's defined then the behavior changes and
>> instance polymorphism is supported.
>>
>>
>> --
> 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.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: [ANN] 1.10.0-beta5

2018-11-08 Thread Timothy Baldridge
The instance based polymorphism is a bit wonky in some cases. Can we get
some sort of spec that tells us what the rules are for resolution? See
these cases where it breaks in some rather strange ways.

Clojure 1.10.0-beta5
user=> (defprotocol ILevel (level [this]))
ILevel
user=> (extend-protocol ILevel
 clojure.lang.IPersistentVector
 (level [this] "interface"))
nil
user=> (extend-protocol ILevel
 Object
 (level [this] "object"))
nil
user=> (level [])
"interface"
user=> (level :key)
"object"
user=> (level (with-meta 'foo {`level (fn [this] "instance")}))
"instance"
user=> (level (with-meta [] {`level (fn [this] "instance")}))
"instance"
user=> (defrecord MyType [] ILevel (level [this] "type"))
user.MyType
;; Fails to override
user=> (level (with-meta (->MyType) {`level (fn [this] "instance")}))
"type"
user=> (defrecord MyType3 [])
user.MyType3
user=> (extend-protocol ILevel
 MyType3
 (level [this] "type"))
nil
user=> (level (->MyType3))
"type"
;; Overrides
user=> (level (with-meta (->MyType3) {`level (fn [this] "instance")}))
"instance"
user=>

So it looks like if someone uses inline protocol extension that class
cannot participate in instance level polymorphism. If however they use
extend on the type after it's defined then the behavior changes and
instance polymorphism is supported.


On Thu, Nov 8, 2018 at 9:24 AM Rick Moynihan 
wrote:

> On Thu, 8 Nov 2018 at 14:36, alex  wrote:
>
>> No, that will not work exactly like Ruby eigenclass, cause eigenclass has
>> a priority when method lookup is performed. In Clojure case if instance's
>> class has implementation of method, it will be preferred instead of meta
>> version. If I understand everything correctly.
>>
>
> Yes, clearly it'll not be exactly like Ruby eigenclasses; because this is
> clojure! :-)  My point was really that it's spiritually similar if you
> consider them as a means of extending individual instances you're given
> with new functionality.  Though yes, thankfully you can't use this for
> monkey patching over existing functionality; but who would want to do
> that?! ;-)
>
> R.
>
>
>>
>> четверг, 8 ноября 2018 г., 12:33:10 UTC+2 пользователь Rick Moynihan
>> написал:
>>>
>>> Cool, so I guess it's the clojure of equivalent of Ruby's eigenclasses:
>>>
>>> f = "some object"
>>> class << f
>>>   def foo
>>>  "new foo method on f"
>>>   end
>>> end
>>>
>>> f.foo # => "new foo method on f"
>>>
>>> It's a shame this mechanism only works for values implementing IMeta,
>>> but I understand the JVM is a little prohibitive in this regard.
>>>
>>> Even so I suppose the main use of this is that it lets a caller give you
>>> a value, and you can return a plussed up version with new capabilities,
>>> without having to return a wrapped value.  Wrapped values are sometimes
>>> problematic because they introduce new representations of existing types,
>>> and this allows an API to return values to the caller that behave the same
>>> as what went in.  Neat!
>>>
>>> R.
>>>
>>> On Tue, 6 Nov 2018 at 15:51, Alex Miller  wrote:
>>>

 On Tuesday, November 6, 2018 at 9:25:31 AM UTC-6, John Schmidt wrote:
>
> Nice to see continued progress on Clojure 1.10!
>
> It is not clear to me what metadata extension provides that is not
> already possible with direct definitions or external extensions. Some
> additional background or a small motivating example would be much
> appreciated in clearing up the confusion!
>

 Metadata extension allows you to implement protocols on a per-value
 basis (the others are type/class-oriented). This opens up a whole new range
 of potential uses for protocols. Rich was already using this approach for
 the new datafy/nav functionality - this made it generic for all protocols.

 Any collection instance can carry metadata, so you can take any
 collection instance and dynamically extend a protocol to it by adding
 metadata. So if you think about something like Component, which has a
 Lifecycle protocol for start/stop, you can now make lightweight components
 without needing to make a type or reify:

 $ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version
 "1.10.0-beta5"}, com.stuartsierra/component {:mvn/version "0.3.2"}}}'
 Clojure 1.10.0-beta5
 user=> (require '[com.stuartsierra.component :as component])
 nil
 user=> (def c (with-meta {:state :init}
 {`component/start (fn [c] (assoc c :state :started))
  `component/stop (fn [c] (assoc c :state :stopped))}))
 #'user/c
 user=> (component/start c)
 {:state :started}
 user=> (component/stop c)
 {:state :stopped}


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

Re: Prototype code for enhanced CIDER code completion for Java methods

2018-10-16 Thread Timothy Baldridge
e,
> vim-fireplace, others?), and try it from one of those tools.  I've only
> tested with CIDER -- in my CIDER I get eldoc, help at symbol at point (I
> wish this displayed javadoc inline), and better code completion.
> 7) Feedback! :-)
>
> I also realize that this stuff is complex enough that there might be some
> set of CIDER settings that solve this problem that I just simply don't know
> about or didn't find.  Love to hear about how others get better Java
> interop code completion.  Some of my clojure projects involve lots of Java
> interop and this would have been so nice to have while writing those
> projects (in my opinion).
>
> I think there are other advantages to this style syntax (besides
> supporting code completion):
>   - Right now I have the jvm macro throw an error if it can't find the
> java symbol -- so you would get a compile time error rather than just a
> reflection warning about a non-existent java method.
>   - In addition to making easier to *write* Java interop, I think it makes
> it easier to *read* Java interop
> I immediately know the Java type while reading the code, no need to
> hunt down the type annotations elsewhere.  I've been writing Java since
> Java 1.1 and I still like the reminder of what class a method is from.
>
>
> ‐‐‐ Original Message ‐‐‐
> On Tuesday, October 16, 2018 4:23 PM, Timothy Baldridge <
> tbaldri...@gmail.com> wrote:
>
> I don't understand why this is needed. Why can't cider code complete on
> the normal method format? What's the problem this code is trying to solve?
>
> 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.
>
>
> --
> 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.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: Prototype code for enhanced CIDER code completion for Java methods

2018-10-16 Thread Timothy Baldridge
I don't understand why this is needed. Why can't cider code complete on the
normal method format? What's the problem this code is trying to solve?

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: New developments in beginner-friendly editing/repl environments?

2018-08-30 Thread Timothy Baldridge
> I never understood how Python is so popular, where spacing is most
important.

> Using tab and shift tab to control parens is really intuitive, because I
want to structure my code anyway and doing it the parinfer way is no big
adjustment.

I think you answered your own question

On Thu, Aug 30, 2018 at 2:14 AM Philipp Neumann 
wrote:

> I never understood how Python is so popular, where spacing is most
> important.
>
> Other than that, I really prefer parinfer over paredit, because I don't
> have to memorize all the key shortcuts to slurp, barf, split and slice.
> Using tab and shift tab to control parens is really intuitive, because I
> want to structure my code anyway and doing it the parinfer way is no big
> adjustment.
>
> --
> 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.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: Is core.async a stackless or stackfull coroutine implementation?

2018-08-26 Thread Timothy Baldridge
They're mostly stackful, but this distinction really doesn't apply to Java
where you can't manipulate the stack like C (or hand written) languages
can. The normal call stack is used for any functions called by a go block,
and for the go block itself. However when a go block pauses, it copies
values from the stack into the heap before completing the pause. This tends
to be rather quick since Java uses pointers for almost everything, and
things that aren't pointers, are integer sized.



On Sun, Aug 26, 2018 at 12:49 AM Didier  wrote:

> I've read a bit about the difference between stackless and stackfull
> coroutines.
>
> But I still don't really understand the difference. And I'm trying to know
> in which camp core.async would fall.
>
> Anyone knows?
>
> --
> 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.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: How to escape a space in a keyword?

2018-08-09 Thread Timothy Baldridge
Have you tried this with Transit instead of EDN? From what I understand by
all this Transit shouldn't have problems with spaces in keywords/strings as
it doesn't print them in the same way, it's more of a marshaling format
than a printer/reader, and you get the big upside of Transit being *way*
faster than EDN.

Aside from that, I'd recommend just introducing a new type. It's easy to
extend EDN, as you've mentioned, so why not just have a new type called
IonSymbol that you use when talking to ION. Use defrecord, and you'll get
equality semantics out of the box.

On Thu, Aug 9, 2018 at 10:27 PM Didier  wrote:

> Ion is a data serialization format from Amazon
> http://amzn.github.io/ion-docs/
>
> One lf its supported data type is symbol, defined as: Interned, Unicode
> symbolic atoms (aka identifiers)
>
> I interact with systems that interchange their data using ION. My systems
> use EDN though internally. Thus I need to convert from ION to EDN and back
> in a lossless manner.
>
> If you give me ION with symbols in them, and I convert them to EDN, I need
> be able to go back to the exact same ION symbol when converting my EDN back
> to ION.
>
> If I make symbols string, I lose the type info, and would convert it back
> to an ION string. This wouod break my clients.
>
> I thought I could get away not having to build a custom representation for
> them in Clojure and EDN, and piggyback on keywords.
>
> It now seems to me like I can still piggyback on keywords when in Clojure,
> since `keyword` and clojure.lang.Keyword appear to support full unicode.
>
> But it seems EDN does not support full unicode serialization for them. So
> I've extended the edn serialization and deserialization so that it does.
>
> I did so by overriding print-method for keywords so that when it prints in
> an unreadable way, it instead outputs a custom literal #myproject/keyword
> "namespace/name". And I've added a reader for this which uses keyword to
> get a Clojure keyword back.
>
> Does any of this seem unsound to anyone?
>
> --
> 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.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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-22 Thread Timothy Baldridge
The whole "conj puts items in a place that's idiomatic for the collection"
makes stuff like `into` possible. In fact, into is (ignoring transients):

(defn into [dest src]
  (reduce conj dest src))

-- 
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: core.async buffered channel behavior

2018-06-27 Thread Timothy Baldridge
The best way to understand how/why this happens is to look at the source of
>!!. In short, the thread making the call doesn't block on the channel. It
starts an async put, then waits on a promise that is delivered by the async
put. So it works something like this:

1) Calling thread creates a promise
2) Calling thread calls put! telling it to deliver the promise once the put
completes
3) Calling thread tries an immediate put! but fails since the channel is
blocked. So the put is enqueued into the channel.
4) Calling thread is canceled (maybe? not sure how this works in nrepl or
whatever is being used here)
5) put! completes, so a different thread executes the callback and delivers
the promise
6) If the thread hasn't been completely killed yet it's possible that it
may get the value from the delivered promise and continue

In short, core.async doesn't support any sort of cancellation without use
of alt!



On Wed, Jun 27, 2018 at 11:18 AM, Justin Smith  wrote:

> I should be more precise there, by "consumed" I meant buffered or consumed.
>
> On Wed, Jun 27, 2018 at 10:17 AM Justin Smith 
> wrote:
>
>> I doubt core.async would ever make promises about the behavior of a
>> blocking put that gets forcibly cancelled. It promises that the blocking
>> put doesn't return until the message is consumed, but that's not the same
>> as promising that the message isn't consumed if the blocking put is
>> forcibly cancelled.
>>
>> On Wed, Jun 27, 2018 at 9:47 AM Didier  wrote:
>>
>>> I think its due to ctrl+c, not sure what it actually does, but maybe it
>>> didn't actually kill the blocked thread?
>>>
>>> --
>>> 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.
>



-- 
“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.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: Clojure on Azul Zing JVM

2018-05-21 Thread Timothy Baldridge
I've worked on several projects where Zing was considered as a solution to
a few problems (normally GC pauses due to really large heaps). But in the
end we never trailed it, due to a few factors:

1) Zing isn't super cheap, it's not that expensive in the grand scheme of
things, but it's an additional cost that had to be added to a project,
normally towards the end when heap sizes or other such things become a
problem. So it's hard to go to management and ask for an increase in
budget.

2) There really isn't a lot of documentation freely available as to how
much Zing helps in a Clojure app. Chicken-and-egg problem here, need more
experience reports to justify the cost, but it's hard to justify the cost
of doing tests with such limited information.

3) Servers and ram are cheap in comparison. So often it was simply cheaper
to create split services up, or partition data in a way that heap sizes
could be reduced. Even something as simple as reducing the JVM heap size
and using memecached on the same box was a cheaper way to solve the
problem.

4) Algorithm changes were also cheaper. In a few cases we moved from using
Clojure's persistent structures to off-heap structures like ChronicleMap or
LevelDB. Or simply walk over the code in question and find ways of storing
less in memory, or caching aggregates instead of whole collections.

In the end there's a theme here. At about 2/3rds of the way through the
project we'd hit an issue with HotSpot and say (hey Zing would help here).
But switching JVMs would require an additional investment. But we already
had a team, so it was simpler to spin off a few developers and have them
solve the worst of the issues and perhaps let a feature slip. In the end, a
small feature not getting in is easier to justify than the purchase of a
new JVM.

So I wish I could work with Zing someday, but each time I've gotten close,
a cheaper solution has presented itself.

Timothy

On Mon, May 21, 2018 at 6:00 PM, Matching Socks 
wrote:

> IBM Java likewise has not excited very much conversation here.  Perhaps
> because Java is "write once, run anywhere"!  The various implementations of
> Java have their strong and weak points, but they will run Clojure in any
> case.
>
> --
> 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.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: Is the vector a sequence?

2018-04-20 Thread Timothy Baldridge
seqable? was added in Clojure 1.9

On Fri, Apr 20, 2018 at 9:54 AM, ru  wrote:

> user=> (seqable? [1 2])
>
>
> CompilerException java.lang.RuntimeException: Unable to resolve symbol:
> seqable? in this context, compiling:(/private/var/
> folders/5j/k0rtjxqn3b57nykc_1jf2xnrgn/T/form-
> init6382892774167052117.clj:1:1)
>
> user=>
>
> пятница, 20 апреля 2018 г., 18:35:45 UTC+3 пользователь tbc++ написал:
>>
>> It's not a seq, but it's seqable.
>>
>> (seq? [1 2]) => false
>> (seqable? [1 2]) => true
>> (seq? (seq [1 2])) => true
>>
>>
>>
>> On Fri, Apr 20, 2018 at 9:33 AM, ru  wrote:
>>
>>> Hi,
>>>
>>> user=> (seq? [1 2 3 4 5])
>>>
>>> false
>>>
>>> user=>
>>>
>>>
>>> Sincerely,
>>>
>>>   Ru
>>>
>>> --
>>> 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.
>>>
>>
>>
>>
>> --
>> “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.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.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: Is the vector a sequence?

2018-04-20 Thread Timothy Baldridge
It's not a seq, but it's seqable.

(seq? [1 2]) => false
(seqable? [1 2]) => true
(seq? (seq [1 2])) => true



On Fri, Apr 20, 2018 at 9:33 AM, ru  wrote:

> Hi,
>
> user=> (seq? [1 2 3 4 5])
>
> false
>
> user=>
>
>
> Sincerely,
>
>   Ru
>
> --
> 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.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: Understanding GraalVM and Clojure

2018-04-19 Thread Timothy Baldridge
GraalVM does a lot of things, and I think it's important to separate these
terms.

GraalVM - most often this is used to refer to a project that was originally
designed to be a implementation of the JVM in Java. So when people ask
"does X run on GrallVM" the question is really "does X run in the JVM".
Clojure runs on the JVM therefore it runs on GraalVM. I've done this, and
it's not that hard to setup.

Truffle - is an AST interpreter framework that allows for highly dynamic
languages to run efficiently on GraalVM. Truffle is valid Java code, so you
can run Truffle on a stock JVM, but it's much faster on GraalVM (or on JVM
of version >= 9). Notice my use of "highly dynamic" earlier. Surprisingly,
Clojure is mostly static, so there's no clear win here to translating
Clojure to Truffle. The exception to this is primitive math, and situations
that use lots of HOF where Truffle could perhaps offer more localized
optimizations that fit into the Clojure programming model. However, you pay
for all this with some rather massive startup time penalties. Most examples
I've seen show Truffle adding seconds on to the startup time of a language.

SubstrateVM - (aka native-image), SubstrateVM attempts to improve the
performance of a Truffle based language by doing image freezing. This
method has been used in other languages, and has existed in the PyPy
toolchain (RPython) for well over a decade. The idea is that you write an
interpreter, then hand SVM a pointer to the start of your interpreter (the
main() function). The framework then analyzes the data needed by that
function and all the functions it calls. All data required by those
functions are also recorded. Then the call graph required to run all these
functions is written out (normally to C or C++) and compiled. The
side-effect is that all the startup time is removed since the interpreter
is "frozen" in a started state. In the terms of Clojure this means that
metadata would be serialized as-is, instead of running the code to create
that metadata on every startup.

Polyglot VM - so in truffle you can have multiple type systems, and
multiple languages all running on Truffle. The framework then allows cheap
interop between these languages. So when GraalVM docs talk about "zero
overhead interop" what they mean is that it's possible to inline a Truffle
based function inside any other truffle based function. Since Truffle
implementations exist for Ruby, Python, LLVM bytecode (think C/C++),
JavaScript, etc. It's easy to see how its possible to have all of these
languages efficiently calling each other on the same VM.

It's not all awesome though. By using SubstrateVM you give up Java
reflection/interop, or have to find a way to embed a full JVM as a Truffle
language (this is being worked on), but every language you add into your
SVM image comes at a cost of startup times, memory usage etc. So most of
the time SVM images stick to a few languages. TruffleRuby for example only
uses Ruby and LLVM (for c interop).

To finish, I think Clojure on Truffle is possible, but it would take a TON
of work. Basically most of clojure.lang.RT would need to be rewritten from
scratch, and I'm not sure how much more in clojure.lang.* would also need
to be rewritten. So the tradeoff is:

A. Current state
- Good enough performance
- Fast enough startup (Clojure starts quickly, it's the deps/tooling that
are slow)
- Requires type hinting to avoid reflection

B. Clojure on Truffle
- More-or-less the same performance
- Faster un-type-hinted math
- (Possibly) Faster transducers/HOF over primitive collections
- No need for type hints
- Massive rewrite
- Huge startup time penalty
- Requires a modern/uncommon JVM (JVM9+ or GraalVM)

Comparing these side-by-side, it looks to me to be a wash. And because of
that I doubt we'll see a TruffleClojure any time soon.

Timothy

On Thu, Apr 19, 2018 at 4:00 AM, Khalid Jebbari 
wrote:

> Hello,
>
> Oracle has just announced GraalVM 1.0 release candidate:
> https://blogs.oracle.com/developers/announcing-graalvm
>
> It mentions a few JVM-based language but not Clojure (maybe just because
> of popularity).
> - Does it mean Clojure is not "compatible" with GraalVM ?
> - Does it mean Clojure needs to be reimplemented in terms of GraalVM's
> Truffle framework ?
> - Does it mean Clojure can be run as a native binary with fast startup
> time and minimized memory footprint ?
>
> If someone with some knowledge could explain to me the relationships
> between Clojure and GraalVM ? Bonus points if Alex Miller answers and share
> the plans, if any, about their integration/interaction.
>
> Thanks a lot in advance. really curious to understand more.
>
> --
> 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

Re: clojure.lang.PersistentVector cannot be cast to clojure.lang.IAtom

2018-04-03 Thread Timothy Baldridge
I think you're calling `deref` on the collection before passing it in? What
it's saying is that `swap!` expects an atom and you handed it a vector. So
either pass in the atom, or return a updated collection by replacing the
call to `swap!` and the `doseq` with `(into collection selecteds)`

On Tue, Apr 3, 2018 at 5:24 PM, Renata Soares 
wrote:

> Good Night,
>
> I have this function:
>
> (defn treat-requests [key-request collection]
> (let [selecteds (filter #((keyword key-request) %) input)]
> (doseq [item selecteds]
> (swap! collection conj item
>
> where input is an output of clojure.data.json/read-str and swap is giving
> this following error:
>
> clojure.lang.PersistentVector cannot be cast to clojure.lang.IAtom
>
> How can I solve it?
>
> Thanks in advance.
>
> --
> 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.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: Writing a text adventure in Clojure

2018-03-29 Thread Timothy Baldridge
You often don't even need functions for this sort of thing. This is what is
often called "data driven" programs. Simply define this as a hashmap with
:description, :items, etc and then a single function that introspects this
data and figures out how to describe the room.

Also you might want to read up on Entity Component Systems. They are often
implemented in OOP languages, but they really are not OOP at all. Here's a
good talk on the subject: https://www.youtube.com/watch?v=TW1ie0pIO_E

On Thu, Mar 29, 2018 at 5:00 PM, Will Duquette  wrote:

> Aha!  How about this, to cut the Gordian knot:
>
>
>1. The fancy room's :description isn't necessarily a simple string.
>It can be a vector of specs, where each spec is a text snippet or a pair
>containing a predicate function and a text snippet.
>2. The (describe) function takes two arguments, the global state and
>the room record.
>3. It steps through the specs, including only those snippets whose
>predicate is true.  The predicates, of course, are predicates on the global
>state.
>
> The room is then a simple object; and the describe method remains purely
> functional.
>
> On Thursday, March 29, 2018 at 3:45:02 PM UTC-7, Will Duquette wrote:
>>
>> I'm an experienced programmer, but a Clojure newbie; as a beginner
>> project, I'm looking into how one would idiomatically write a text
>> adventure of sorts in Clojure.  I'm less interested in producing a playable
>> game than I am in learning how to do such a thing in a proper functional
>> style.
>>
>> Suppose in this game I have a room whose description changes based on a
>> global flag.  For example, there's something in the Fancy Room that you
>> won't notice until you've reached the major plot point.
>>
>> The world map is (for the sake of argument) a hash-map whose keys are the
>> room IDs and whose values are room records, where each record is a hash-map.
>>
>> (def world {:fancy-room {:name "Fancy Room" :description "This is a fancy
>> room." ...}})
>>
>> I'm aware that I could use a (defstruct) or (defrecord); I'm keeping it
>> simple for now.  Then, the flags are saved in a ref; the intent is that
>> mutable set is segregated, so that it can more easily be written to a save
>> file.
>>
>> ;; Global set of flags
>> (def flags (ref #{})
>>
>> (defn flag-set [flag]
>>(dosync (alter flags conj flag))
>>
>> ;; When the major plot point is reached
>> (flag-set :major-plot-point-reached)
>>
>> Normally, to describe a room you just return its :description.
>>
>> (defn describe [room] (:description (world get room)))
>>
>> But for the :fancy-room, the returned description depends on the global
>> flag, and it will be specific to :fancy-room.  I could add this logic
>> directly to the (describe) function's body, but that would be ugly.  What
>> I'd like to do is attach a lambda to the :fancy-room in some way.  The
>> (describe) function looks for a :describer, and if it's there it calls it;
>> and if not it just returns the :description:
>>
>> (defn describe [entity]
>> (if (:describer entity)
>>   ((:describer entity) entity)
>>   (:description entity)))
>>
>> *Question 1*: this works, but it looks ugly to me; I figure there's a
>> better, more idiomatic way to do this kind of thing that's probably obvious
>> to anyone with any real experience.  Multimethods, maybe?  Define a Room
>> protocol, then let most rooms be NormalRoom records, but let :fancy-room be
>> a FancyRoom record?
>>
>> *Question 2*: Whatever code actually computes the description, it will
>> need access to the :major-plot-point-reached flag.  What's the cleanest way
>> to give the description code access to the flags ref?  It could simply
>> access "@flags" directly:
>>
>> (if (:major-plot-point-reached @flags)
>>   "This is a fancy room.  Hey, that light sconce looks movable!"
>>   "This is a fancy room.")
>>
>> But that doesn't seem properly functional.  Would it be better to pass
>> the game state into each method?
>>
>> (defn describe [entity state]
>>   (if (:describer entity)
>>  ((:describer entity) entity state)
>>  (:description entity)))
>>
>> Any ideas?
>>
> --
> 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 

Re: D + Clojure?

2018-03-27 Thread Timothy Baldridge
Nice! I think I used this app the other day when working on a campaign and
didn't know it was using Clojure. I'd be open to contribute in my spare
time. What's the process for getting involved?

Timothy Baldridge

On Tue, Mar 27, 2018 at 2:03 PM, Larry Christensen <red...@orcpub.com>
wrote:

> I have a Dungeons & Dragons app built in Clojure and ClojureScript. With The
> Original OrcPub <http://www.orcpub.com> and The New OrcPub
> <https://www.orcpub2.com> I have about 300K monthly users and have been
> used by millions of people over the past few years. I'm looking for people
> who might want to contribute to building some cool features for a fun app!
>
> -Larry Christensen a.k.a RedOrc
> Supreme Leader
> OrcPub
>
> --
> 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.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: Any better client then telnet for connecting to a socket repl server?

2018-03-03 Thread Timothy Baldridge
Sadly NREPL isn't a REPL it's a RPC protocol transport for remote
controlling a Clojure instance.

You might look into rebel: although I'm not sure how well that plays with
remote terminals.  https://github.com/bhauman/rebel-readline.

Also look into doing some of this with readline. Perhaps you can pipe
something together via netcat, GPL readline, and socket servers?

Also Emacs provide a lot of this support via inferior lisp. So, like any
lisp you can tell emacs that your inferior lisp command is a telnet command
and it all "just works".

Timothy

On Sat, Mar 3, 2018 at 11:17 AM, Chris Shellenbarger 
wrote:

> Can you use NREPL?  https://github.com/clojure/tools.nrepl
>
> This seems to be what most tools that provide a REPL are built on top of
> (Cursive, CIDER, etc).
>
>
> On Friday, March 2, 2018 at 7:49:45 PM UTC-6, Didier wrote:
>>
>> I want to connect to a Clojure socket repl server, but telnet is a really
>> terrible repl experience. Anyway I can have a better client to connect to
>> it that would have some better support for history, backspace, maybe even
>> some auto-complete, highlight, etc. Whatever I can get over telnet?
>>
>> 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.
>



-- 
“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.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: Why does the `def-` not exist?

2018-02-26 Thread Timothy Baldridge
I much more prefer putting implementation details into separate namespaces.
>From there it's simple to mark them as :no-doc in some documentation tools
so that the vars don't get published. That way I can still test all my
code, and yet I can commit to only those namespaces that have published
APIs.

Or even just putting implementation details behind foo.bar.impl.* So that
it's clear that the contents of these namespaces should not be relied on.
This is what core.async does, and what a lot of my personal projects do.

Timothy

On Mon, Feb 26, 2018 at 8:47 PM, Didier  wrote:

> I’d even be happy if the default was private for def
>>
>
> I actually prefer private everything by default. Its the public things you
> want to be reminded to think through carefully. And Var access is pretty
> straightforward, in case your using a lib and they forgot to make something
> public you really need, but its way too late to change a default like that.
>
> I think we have to ask ourselves what's the use cases where we use private
> on a Var?
>
> I can think of:
>
>- When on a function - Implementation details, don't depend on it, it
>could change at any time in breaking ways, ie, use at your own risk.
>- When on state - You should not read this data directly, its
>representation is possibly not easy to consume (another public facing
>mechanism exist to get a better representation of it), or you can't depend
>on the shape of this data not to change or this data even existing long
>term. Thus again, its implementation details.
>- When on state - You should not write to this data directly, it has
>strict invariants, and so if you do decide to write to it, be careful you
>understand and maintain them.
>
> Can anyone think of more use cases?
>
> I'm not even sure the concept of private and public make sense. Could
> there be a better construct to solve these use cases?
>
> I feel private would make sense in a security perspective, if there was no
> way to bypass it, for say running untrusted code within your code, but
> that's not what private does in any way.
>
> On Monday, 26 February 2018 17:41:15 UTC-8, Alex Miller wrote:
>>
>> We're not going to add def-. There is regret over even adding defn-, but
>> we don't take things away...
>>
>> At one point all of the current metadata niceties didn't exist (used to
>> be #^{:private true} some may recall) and defn- seemed worth doing I
>> presume (pre-dates my involvementT). But then that was all simplified down
>> to just ^:private and it's preferred to compose the pieces rather than copy
>> N things.
>>
>> There used to be a slew of these in the old clojure-contrib (
>> https://github.com/clojure/clojure-contrib/blob/master/modu
>> les/def/src/main/clojure/clojure/contrib/def.clj - but no def- !).
>>
>> How often do you def things anyway (much less private things)?
>>
>> On Monday, February 26, 2018 at 1:50:40 PM UTC-6, Leon Grapenthin wrote:
>>>
>>> I have written enough Clojure so that I can assure you that every few
>>> days when I type ^:private again I am still annoyed by it. Not every time,
>>> but probably every second or third time.
>>>
>>> Its just in the way of the prototyping typing (micro-)flow. SHIFT-6 you
>>> don't hit so often so you have to hit it right. On german keyboards, by the
>>> way, ^ is a much more annoying character to type. Then a colon, did I miss
>>> the colon? What did I want to do again?
>>>
>>> When prototyping an API ns its important to distinguish what is private
>>> and what isn't. If only I could just write def- without any overhead.
>>>
>>> First world aka best language problems, I know...
>>>
>>> But whats left for an enthusiast except bikeshedding? We both know that
>>> a JIRA discussion on this will not happen due to a lack of importance. And
>>> unless somebody manages to convince Rich, this feature won't happen.
>>>
>>> Fair enough. I'd consider myself a power user since 1.5.1 and value its
>>> conservative governance above every other kind.
>>> The "lets not start postfixing lots of macros with -" argument a good
>>> one in general and probably was a good one at the time. But not in this
>>> case because defn and def are the two most used and most elementary top
>>> level forms.
>>>
>>> This argument didn't convince anyone who has asked me about this. The
>>> counter argument goes "I don't want the - postfix for anything else, just
>>> for def because I use it a lot" -rightfully so.
>>>
>>> The lack of def- is just unnecessary typing overhead in lots of cases.
>>> It could be removed at the cost 5m on a beautiful day. I'd appreciate it :)
>>>
>>> On Monday, February 26, 2018 at 6:52:51 PM UTC+1, Alexander Yakushev
>>> wrote:

 - Not that often. When I know for certain, I add ^:private. Not like
 it's much more work. If I didn't know ahead of time, I would forget to add
 the private flag in either case.
 - Never.
 - Can't recollect such an event.
 - A 

Re: transients problem

2018-02-24 Thread Timothy Baldridge
>>  If it happens to work, it is accidental, and should not be relied on.

Yes, and no. The actual order may change between Clojure releases (last
time it changed was with 1.6), or between two equal collections, but the
ordering will not change between two calls to `seq` on the same instance of
a hashmap or set. Therefore you absolutely can rely on this working:
(zipmap (keys m) (vals m)), you will never get a jumbling of keys and
values. Most of the time when people call seq on a set or map they want to
iterate over it, and that's fine.

On Sat, Feb 24, 2018 at 2:32 PM, Didier  wrote:

> is there a way round it?
>>
>
> Something else I need to point out is that you really should not use a Set
> for order. Sets are specifically unordered, and provide no guarantees of
> order. Try calling first, second and last on #{1 2 3} for example, you'll
> probably get things back in a different order.
>
> If it happens to work, it is accidental, and should not be relied on. If
> you want order, use a Vector or a List. Vectors are probably going to feel
> more natural, since they append to the end.
>
> You use a Set over a Vector most of the time, because you are specifically
> telling the consumers of the collection not to rely on order, that the
> order is meaningless and no logic should be derived from it. Similarly, if
> you use a Vector over a Set it should be because the order is guaranteed
> and does matter, and consumers of the collection are welcomed to assume
> this and build logic that is order dependent.
>
> That said, yes there is a way around it, you can call persistent! to get
> back a PersistentHashSet, and then call first on it. Going from a transient
> to a persistent is O(1), so its really fast. You can keep alternating
> between persistent and transient as your needs change between reading and
> iterating back to updating.
>
> Reading and iterating over a persistent is just as fast, the transient
> provides no value. Transient will only make updates and inserts faster.
>
> On Saturday, 24 February 2018 07:15:02 UTC-8, Alan Forrester wrote:
>
>> Calling (first #{1}) gives the result 1.
>>
>> Calling (first (transient #{1})) gives an error:
>>
>> “IllegalArgumentException Don't know how to create ISeq from:
>> clojure.lang.PersistentHashSet$TransientHashSet  clojure.lang.RT.seqFrom
>> (RT.java:550)”
>>
>> Is this behaviour intended?
>>
>> And whether or not this is intentional is there a way round it?
>>
>> Alan Forrester
>>
>>
>> --
> 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.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: transients problem

2018-02-24 Thread Timothy Baldridge
Yes, transients mutate when updated. Seqs over sets are a immutable view
over a collection. So if someone did get this to work, the implementation
could be incorrect. And you could get something really strange like this:

(def s (transient #{1 2}))
(def sq (seq s))
(first sq) => 1
(disj s 1)
(second sq) => nil

There's a dozen things that could go really wrong here, but that's the gist
of it.

On Sat, Feb 24, 2018 at 8:14 AM, 'Alan Forrester' via Clojure <
clojure@googlegroups.com> wrote:

> Calling (first #{1}) gives the result 1.
>
> Calling (first (transient #{1})) gives an error:
>
> “IllegalArgumentException Don't know how to create ISeq from: clojure.lang.
> PersistentHashSet$TransientHashSet  clojure.lang.RT.seqFrom (RT.java:550)”
>
> Is this behaviour intended?
>
> And whether or not this is intentional is there a way round it?
>
> Alan Forrester
>
>
> --
> 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.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: If Clojure is to blame for the majority of the startup time, why doesn't ClojureScript proportionally slow down the JavaScript startup time also?

2018-01-25 Thread Timothy Baldridge
I would suggest everyone here read this document:
https://dev.clojure.org/display/design/Improving+Clojure+Start+Time It goes
into a lot of detail on prior work in this area, and I'd say the benchmarks
on it should be quite informative.

But let me also go into a bit more detail into how CLJS differs from CLJ in
how it accesses global function definitions:

In CLJs, clojure core contains a lot of definitions that look something
like this:

clojure.core.conj = function () {... clojure.core.some_fn(...) . }

The cost of creating that global function is then the cost of 2 lookups
(clojure in the global namespace, core in clojure), the creating of a JS
function object, and the assigning of that function to the core object. The
internal call to some_fn doesn't matter at load-time because of
Javascript's late binding.

In the JVM this happens:

1) A class is loaded that implements the IFn or AFn interfaces
2) The methods on this class must be loaded and the bytcode parsed, and
validated
3) The static constructor on this method is run
4) Inside the static constructor there are calls to find Vars. In the case
of the above function this would be a lookup to clojure.core.some_fn. This
is done for every var referenced by this function
5) Any non-native constants must be new'd up. This includes hashmaps,
vectors, lists, keywords (which must be interned), symbols, etc.
5) The clojure.core.conj var is created
6) The contents of the var are set to the function that was loaded (and
new'd). Synchronization doesn't matter here as there are no other threads
that can see this Var.
7) The metadata for the function is created. Most of the time this includes
creating a hashmap with at least 2-3 values.
8) The metadata for the var is set.

The systems in play here are completely different. So I re-state what I
said before: it's apples-to-oranges.

But I'd love to see more benchmarks in this thread, so far we only have
opinions.


On Thu, Jan 25, 2018 at 9:37 PM, Timothy Baldridge <tbaldri...@gmail.com>
wrote:

> >> If Var reification is part of the slowness of Clojure startup over
> Java's
>
> It's really not. If you completely removed vars from Clojure on the JVM,
> Clojure wouldn't be faster by any measurable amount. If someone has
> benchmarks that say that Vars themselves are the cause of Clojure JVM's
> slower startup, then I'd love to see those benchmarks, because there's most
> likely a serious flaw in the measurements.
>
> On Thu, Jan 25, 2018 at 9:34 PM, Didier <didi...@gmail.com> wrote:
>
>> Really, any comparisons between JS and JVM startup times are not useful
>>> at all.
>>
>>
>> I'd say its useful to me, if anything because I've learned quite a few
>> things already from this comparison, and I hope to learn more.
>>
>> If Var reification is part of the slowness of Clojure startup over
>> Java's, and ClojureScript managed without it, yet it delivered 90% of the
>> practical benefits of Var reification, I could see a potential here maybe.
>> Something similar to a dynamic or AOT. Flagging some Vars which need not be
>> reified, or compiling to non reified Vars if fast startup time is what the
>> user would rather have. I could see this being desirable for use cases like
>> AWS Lambda, or small scripts, if it had a drastic startup improvement.
>>
>> The concurrency issue is interesting, and would definitely be unique to
>> Clojure over ClojureScript. First time I hear about this being a possible
>> bottleneck for startup time. Are the concurrency checks java's? Or are
>> these higher level Clojure concurrency checks? Is there possible
>> improvement from the Clojure side of them to make them faster?
>>
>> @tbc++ seems to imply the apples to oranges are due to the platforms, and
>> I can accept this to be true, except that I've seen suggestions that the
>> slow startups are due to either Clojure's implementation causing startup
>> bottlenecks, or Clojure's core design preventing any kind of fast startup
>> implementation. Meaning the culprit is Clojure and not the JVM. But as I
>> find myself thinking about ClojureScript, I wonder if this is true. If
>> Clojure's core design is the bottleneck, then why doesn't ClojureScript
>> suffer too? And so, maybe its because it has altered some core design
>> choices, like concurrency and Var reification. Is it just that? Or is there
>> also bottleneck in the current Clojure implementation on the JVM, which
>> were implemented more efficiently on ClojureScript? I know Alex Miller is
>> working on some of those, and every version of Clojure optimizes, but I've
>> also heard nothing here is expected to create a game changer improvement
>> (appart from possibly grouping functions under one class). And if its
>> n

Re: If Clojure is to blame for the majority of the startup time, why doesn't ClojureScript proportionally slow down the JavaScript startup time also?

2018-01-25 Thread Timothy Baldridge
>> If Var reification is part of the slowness of Clojure startup over Java's

It's really not. If you completely removed vars from Clojure on the JVM,
Clojure wouldn't be faster by any measurable amount. If someone has
benchmarks that say that Vars themselves are the cause of Clojure JVM's
slower startup, then I'd love to see those benchmarks, because there's most
likely a serious flaw in the measurements.

On Thu, Jan 25, 2018 at 9:34 PM, Didier  wrote:

> Really, any comparisons between JS and JVM startup times are not useful at
>> all.
>
>
> I'd say its useful to me, if anything because I've learned quite a few
> things already from this comparison, and I hope to learn more.
>
> If Var reification is part of the slowness of Clojure startup over Java's,
> and ClojureScript managed without it, yet it delivered 90% of the practical
> benefits of Var reification, I could see a potential here maybe. Something
> similar to a dynamic or AOT. Flagging some Vars which need not be reified,
> or compiling to non reified Vars if fast startup time is what the user
> would rather have. I could see this being desirable for use cases like AWS
> Lambda, or small scripts, if it had a drastic startup improvement.
>
> The concurrency issue is interesting, and would definitely be unique to
> Clojure over ClojureScript. First time I hear about this being a possible
> bottleneck for startup time. Are the concurrency checks java's? Or are
> these higher level Clojure concurrency checks? Is there possible
> improvement from the Clojure side of them to make them faster?
>
> @tbc++ seems to imply the apples to oranges are due to the platforms, and
> I can accept this to be true, except that I've seen suggestions that the
> slow startups are due to either Clojure's implementation causing startup
> bottlenecks, or Clojure's core design preventing any kind of fast startup
> implementation. Meaning the culprit is Clojure and not the JVM. But as I
> find myself thinking about ClojureScript, I wonder if this is true. If
> Clojure's core design is the bottleneck, then why doesn't ClojureScript
> suffer too? And so, maybe its because it has altered some core design
> choices, like concurrency and Var reification. Is it just that? Or is there
> also bottleneck in the current Clojure implementation on the JVM, which
> were implemented more efficiently on ClojureScript? I know Alex Miller is
> working on some of those, and every version of Clojure optimizes, but I've
> also heard nothing here is expected to create a game changer improvement
> (appart from possibly grouping functions under one class). And if its
> neither the implementation, or the core design choices, then I have to
> conclude that it is in fact the JVM's fault, in that its core design is
> making what Clojure does on startup more expensive then say the V8 design.
> Which one of those three things (or possible combination is it) is what I'm
> trying to seek answer for here.
>
> Thanks everyone,
> Didier
>
> On Thursday, 25 January 2018 12:53:03 UTC-8, tbc++ wrote:
>>
>> Really, any comparisons between JS and JVM startup times are not useful
>> at all. For a long list of reasons, not limited to:
>>
>> * CLJS doesn't have Vars, CLJ does
>> * JS VMs are highly tuned for excellent startup times
>> * JVM Bytecode is a binary format expressing classes, JS files are text
>> files expressing functions and data transformations
>> * JVM is class based, JS is prototype based
>> * JVM is multithreaded and designed to handle several GB of data, JS VMs
>> are single threaded and designed to often deal with less than a GB of data.
>> * HotSpot (and most) JVMs are method JITS, JS engines often use many
>> profiling methods that are closer to that of a tracing JIT
>> * The JVM performs extensive security analysis on loaded bytecode, JS
>> engines disallow most security flaws via syntax restrictions
>> * CLJS supports tree shaking and minifcation.
>>
>> All this adds up to an apples-to-oranges comparison. They are completely
>> different platforms, the numbers between the two won't be close, and
>> drawing any sort of comparison between the two isn't very useful at all.
>>
>> --
>>
>> * No multithreaded safety in vars is not what takes up most of the
>> startup time in Clojure. We're talking about single threaded access (var
>> initing isn't multithreaded) to a primitive that is updated via a CAS. The
>> highest cost you'll see accessing a var in this situation is somewhere in
>> the range of a cache miss or two.
>>
>>
>>
>> On Thu, Jan 25, 2018 at 1:26 PM, Stephen Nelson 
>> wrote:
>>
>>> The JVM is concurrent whereas Javascript VMs are singled-threaded. Var
>>> initialisation in Clojure uses concurrency primitives to ensure that
>>> namespaces are always consistent for all threads, whereas Clojurescript
>>> simply assigns to variables. Our profiling of Clojure on the JVM indicates
>>> that a lot of the time spent in namespace initialisation is spent 

Re: Officially support Vert.x

2018-01-10 Thread Timothy Baldridge
A few other points of design:

1) Move the requires into the `ns` form:

(ns example.simple-http-server
  (:require [io.vertx.clojure.core.core :as core]
[io.vertex.lang.clojure.vertx :as vertx]))

2) If you make sure that your functions always return the first argument
passed to them you can leverage the `->` macro:

(-> req
 request/response
 (response/put-header "content-type" "text/plain")
 (response/end "Hello from Vert.x!"))


Just some things to think over.

Timothy

On Wed, Jan 10, 2018 at 6:47 AM, Feuer Au  wrote:

> Thanks a lot
> we modify the hello code to following:
>
> (ns examples.simple-http-server)
>
> (require
>  '[io.vertx.clojure.core.core :as core]
>  '[io.vertx.lang.clojure.vertx :as vertx]
>  '[io.vertx.lang.clojure.http-server :as server]
>  '[io.vertx.lang.clojure.http-server-request :as request]
>  '[io.vertx.lang.clojure.http-server-response :as response])
>
> (defn handle-request [req]
>   (let [response (request/response req)]
> (response/put-header response "content-type" "text/plain")
> (response/end response "Hello from Vert.x!")))
>
> (defn start [vertx]
>   (let [http-server (vertx/create-http-server vertx)]
> (server/request-handler http-server (core/handler handle-request))
> (server/listen http-server 8080)))
>
>
> and we also have one problem
>
> On Wednesday, January 10, 2018 at 6:52:53 PM UTC+8, Gary Verhaegen wrote:
>>
>> It’s not clear what the "do" is supposed to mean in those defns (unless
>> there’s some deep dark magic going on, they are currently not doing
>> anything and you can just remove them), and you very likely want "let"
>> instead of "def" for the local variables.
>>
>> def in Clojure does not follow lexical scoping rules; it’s always a
>> global name.
>>
>> On 10 Jan 2018, at 10:25, Feuer Au  wrote:
>>
>> And here is the simple example "Hello from Vert.x!" like other languages
>> on the Vert.x official frontpage:
>>
>> (ns examples.simple-http-server)
>>
>> (require
>>  '[io.vertx.clojure.core.core :as core]
>>  '[io.vertx.lang.clojure.vertx :as vertx]
>>  '[io.vertx.lang.clojure.http-server :as server]
>>  '[io.vertx.lang.clojure.http-server-request :as request]
>>  '[io.vertx.lang.clojure.http-server-response :as response])
>>
>> (defn handle-request [req]
>>   do
>>   (def response (request/response req))
>>   (response/put-header response "content-type" "text/plain")
>>   (response/end response"Hello from Vert.x!"))
>>
>> (defn start [vertx]
>>   do
>>   (def http-server (vertx/create-http-server vertx))
>>   (server/request-handler http-server (core/handler handle-request))
>>   (server/listen http-server 8080))
>>
>> Pretty straight forward, but we could make it better
>> e.g. combine different namespaces into one single would be nice
>> and we got pure functions in different namespaces
>> hmmm, it looks nice.
>>
>> --
>> 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.
>



-- 
“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.google.com/group/clojure?hl=en
--- 
You received this message because you are 

Re: Officially support Vert.x

2017-12-30 Thread Timothy Baldridge
Multi-process polyglot systems I understand, they aren't common, but I've
seen them. In most cases, immutable queues and HTTP APIs work great. But
(and pardon my bluntness), why would I ever want a polyglot single process
system? That sounds like a major design mis-step. The overhead of mental
context switching would be rather oppressive, not to mention the problem of
finding new hires that know all the languages you use on your service.
Additionally, systems like Vert.x that try to provide a common IO layer for
a bunch of languages end up catering to a lowest common denominator. When I
last looked at Vert.x I was struck by how little of the platform I needed
because Clojure properly handled things like concurrency and data-first
programming.

So I'd caution about making polyglot single-process systems a
"requirement". I've been building systems for years and rarely encountered
a problem that required more than one language, and those that did worked
great via communicating via queues (even in-memory queues), DBs and HTTP.

Timothy

On Sat, Dec 30, 2017 at 8:31 AM, Feuer Au  wrote:

> Hmm
> yes it is almost an absolute requirement since we have already invested a
> lot in Java, Kotlin, Javascript and other languages based on Vert.x
> and for Clojure & Haskell are pretty new candidates for us, we need to
> find a way to persuade our programmers to use these languages
> and Vert.x is almost the only way to persuade our lovely programmers to
> give it a try
> If we dont use Vert.x, those guys may resist to try a new language since
> they need to get used to many new softwares e.g. maven -> leiningen
> some times people may not like changes^_^
>
> On Friday, December 29, 2017 at 9:11:34 PM UTC+8, Gary Verhaegen wrote:
>>
>> Is vert.x an absolute (external) requirement, or is that a tool you want
>> to use to achieve some goal? If the latter, maybe there are other tools in
>> the Clojure ecosystem that you could use instead?
>>
>> On 29 December 2017 at 13:49, Toby Crawley  wrote:
>>
>>> The short answer is no, there is no Clojure support for Vert.x 3 that I
>>> know of.
>>>
>>> The longer answer: I wrote the Clojure language module for Vert.x 2,
>>> which had a pretty low usage rate, partially because core.async was
>>> released around the same time. When Vert.x 3 was being written, the Vert.x
>>> team asked me if I wanted to build a Clojure module for it. I declined
>>> because I didn't think there was enough interest to warrant the effort, and
>>> because Vert.x 3 moved to a code generation system for language modules
>>> that was geared towards object-oriented languages, which would have been
>>> difficult to use for generating a Clojure api.
>>>
>>> - Toby
>>>
>>>
>>> On Thu, Dec 28, 2017 at 10:53 PM, Feuer Au  wrote:
>>>
 Hi All,

 Curious about Vert.x is officially supported?

 We tried to use some new languages on JVM e.g. Scala, Kotlin etc.

 and be interested in using some relatively purely functional
 programming languages and so far Clojure is our best bet

 but unfortunately couldn't find native Clojure api on Vert.x but got
 official support for Kotlin

 so just wonder is there any official support for Vert.x in Clojure?

 Cheers!
 --

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

Re: Slow -main function termination by pmap

2017-12-19 Thread Timothy Baldridge
Sometimes there's some weird interop with stuff like pmap and program
termination. What happens if you end your program with this function:
https://clojuredocs.org/clojure.core/shutdown-agents

On Tue, Dec 19, 2017 at 1:05 PM, Jacek Grzebyta 
wrote:

> Hi,
>
> I have multi -mains project. Thus the execution looks like:
>
> java -cp location/file.jar some.method ..
>
>
> One -main method looks like:
>
> (defn -main
>   [& args]
>   (let [validated (validate-args args)]
> (if (:msg validated)
>   (println (st/join \newline (:msg validated)))
>   (run validated))
> (log/debug "finish")))
>
>
> There is nothing special in that except in the run time I have displayed
> the last log "finish" and the program termination is done after ~1 min
> later what is annoying. I found it is caused by deeply hidden pmap even if
> it is wrapped by doall. I thought after pmap returns results all threads
> are finished i.e. the main thread waits until all sub threads will be
> finished. If I am right what else can cause the delay? The threads pool
> manager?
>
> Tanks a lot,
> Jacek
>
> --
> 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.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: functional implementation of core.async primitives

2017-12-13 Thread Timothy Baldridge
Great! So while this works, you'll still have a few problems, namely in
places that are not in a tail call position.
For example, core.async support this sort of behavior

;; inside an argument list (not a let)
(go
  (println "GOT Value" ( wrote:

> I just added `goloop` and `goconsume` to the Clojure implementation, with
> version of `recur` called `gorecur`.
>
> *Example:*
>
>> repl>
>> (def ch (chan))
>> #'functional-core-async.core/ch
>>
>> repl>
>> (goconsume [v ch]
>>   (if (= :ok v)
>> (gorecur)
>> (println "done")))
>> #object[java.util.concurrent.ArrayBlockingQueue 0x30bb0ac9 "[[]]"]
>>
>> repl>
>> (>!! ch :ok)
>> nil
>>
>> repl>
>> (>!! ch :ok)
>> nil
>>
>> repl>
>> (>!! ch :ok)
>> nil
>>
>> repl>
>> (>!! ch :nope)
>> done
>> nil
>>
> --
> 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.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: IF, WHEN or SOME

2017-12-11 Thread Timothy Baldridge
I talked a bit about this in my video on Boolean Blindness:
https://www.youtube.com/watch?v=K1LaaJMscCc

Might be worth a watch.

On Mon, Dec 11, 2017 at 4:56 PM, Stephen Feyrer 
wrote:

> Hi there,
>
> I have been trying to shake this thought for a while now.  Essentially, my
> thought was if you can return a function why not decision component of an
> IF, WHEN or SOME statement?  That would give you a re-usable named choice.
>
> Then you could write:
>
> (celebration: do-something do-something-else)
>
>
> This would be equivalent to writing:
>
> (def success [apples bananas pears])
>
> (defn celebration: [x y] (if (empty? success) x y))
>
> (celebration: (do-something do-something-else))
>
>
> I'm reasonably certain of the foolishness of this thought but
> occasionally, I have doubts.
>
> Maybe I'm barking up the wrong tree or possibly I've seen something like
> this before and forgotten about it.  Perhaps, this is just taking things
> too far...  Either way, it's deferring the choice until it's needed.  In
> the right hands it could make for more readable code.
>
> For completeness sake, to define the first form above you'd use:
>
> (defc celebration: (if (empty? success)))
>
>
> A more usable example might look like:
>
> (def nums [1 2 3 4 5 6 7 8])
>
> (defc even-nums: (some (even? nums)))
>
> I guess this makes the real question, is it a good thing to be able to
> defer choice like this?
>
>
> Btw, defc would be like def-choice but other options might be deft -
> def-test or defp - def-predicate.
>
>
> --
> Kind regards
>
> Stephen
>
> --
> 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.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: State & GUIs

2017-12-02 Thread Timothy Baldridge
I think the major leap functional languages (esp. CLJS because that's where
it started) have made in the UI world is in the area of React-style virtual
DOM setups.

The overall view is this:
datamodel -> view generation -> dom differ -> UI -> events -> datamodel

The idea being that you can code in a very declarative way, and allow the
framework to diff the UI with what the previous view of the UI was. So
although this model is not strictly functional (events do have side
effects) it is a declarative dataflow, and for me that's revolutionized how
I do UI work.

This model with originally prototyped with React, but then Om in
ClojureScript introduced immutable data that can drastically cut down on
the complexity of the React diffing model.

All that's happened in about the last 4 years. And since then we've seen a
lot of ideas from ClojureScript move into the JS world and back into React
itself. From there, libraries such as my fn-fx lib (mentioned previously)
are simply a React-esque virtual dom over JavaFX. Sadly though, these non
JS libraries don't get a lot of exposure mostly because the vast majority
of UI apps are in the browser. It's been almost 10 years since a client has
asked me for a non-browser app.

Timothy


On Sat, Dec 2, 2017 at 6:41 PM, Raoul Duke  wrote:

> random tangential food for thought:
> https://groups.google.com/forum/#!searchin/elm-discuss/
> Discussion$20on$20saying$20farewell$20to$20FRP$20|sort:
> relevance/elm-discuss/6U74_aNXC04/UY8dIIh-CQAJ
>
> --
> 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.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: Unexpected performace of transducers

2017-11-27 Thread Timothy Baldridge
>> Also, I think the transducer version should always be faster, no matter the
size of the source collection (no threshold).

It's a bit more complicated than that, mostly because transducer pipelines
require about 2 allocations per step during creation. Also, most of the
performance boost from transducers is due to less garbage being created,
and some times the heap of the JVM is so large you'll never see much change
from switching to transducers.

Don't get me wrong, transducers are great and I often default to them over
seqs, but in micro-benchmarks like this there's too much in play to always
see a 100% performance boost.

On Mon, Nov 27, 2017 at 12:55 PM, David Bürgin  wrote:

> Jiacai –
>
> I saw you updated the gist. Just in case it passed you by: performance
> profits from the source collection being reducible. So pouring ‘dataset’
> into a vector beforehand should speed up the processing quite a bit.
>
> Also, I think the transducer version should always be faster, no matter
> the size of the source collection (no threshold).
>
>
> --
> David
>
> --
> 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.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: Unexpected behaviour of transient map

2017-11-24 Thread Timothy Baldridge
But this behavior is already documented in the official transients overview
at http://clojure.org/transients

On Fri, Nov 24, 2017 at 5:46 PM Matching Socks  wrote:

> I would go so far as to (light-heartedly) call the "assoc!" docstring
> booby-trapped.
>
> There is an open issue in Jira for it.  Go vote:
> https://dev.clojure.org/jira/browse/CLJ-1385
>
> --
> 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.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: functional implementation of core.async primitives

2017-11-22 Thread Timothy Baldridge
I'm not exactly sure how the library works, honestly. It's seems that we
still don't have parking take, instead we have callbacks again? I'd love to
see an implementation of something like this with your library:

(go
  (println "Count"
(loop [acc 0]
  (if-some [v ( wrote:

> Thanks for the encouragement, Jay!
> I ported the library  over to
> JS, and now we have coroutines in vanilla JavaScript!
> Porting it to other systems should be fairly straightforward. 
>
> - Divyansh
>
> --
> 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.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: spec for an agent

2017-11-17 Thread Timothy Baldridge
And google doesn't like that link, copy-paste that URL including the "!"

On Fri, Nov 17, 2017 at 2:00 PM, Timothy Baldridge <tbaldri...@gmail.com>
wrote:

> All clojure ref types have validators that are perfect for this use case:
> https://clojuredocs.org/clojure.core/set-validator!
>
> On Fri, Nov 17, 2017 at 1:58 PM, Peter Hull <peterhul...@gmail.com> wrote:
>
>> I am using agents whose state is a map. I have a spec for this map,
>> ::agent-state. What's the best way to validate the agent?
>>
>> I have:
>> (s/valid? #(s/valid? ::agent-state (deref %)) myagent)
>>
>>
>>
>> Is this there a neater way to do this? (I actually want the spec to apply
>> to the ret value of an s/fdef)
>>
>> --
>> 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)
>



-- 
“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.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: spec for an agent

2017-11-17 Thread Timothy Baldridge
All clojure ref types have validators that are perfect for this use case:
https://clojuredocs.org/clojure.core/set-validator!

On Fri, Nov 17, 2017 at 1:58 PM, Peter Hull  wrote:

> I am using agents whose state is a map. I have a spec for this map,
> ::agent-state. What's the best way to validate the agent?
>
> I have:
> (s/valid? #(s/valid? ::agent-state (deref %)) myagent)
>
>
>
> Is this there a neater way to do this? (I actually want the spec to apply
> to the ret value of an s/fdef)
>
> --
> 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.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: functional implementation of core.async primitives

2017-11-15 Thread Timothy Baldridge
I don't think the go blocks play well with the back-pressure. The code I
present here deadlocks the scheduler:
https://github.com/divs1210/functional-core-async/issues/1

On Wed, Nov 15, 2017 at 2:17 PM, Jay Porcasi  wrote:

> interested to hear any feedback on these features
>
>
> On Wednesday, November 15, 2017 at 3:52:24 PM UTC+7, Divyansh Prakash
> wrote:
>>
>> Hi!
>>
>> Thank you for your feedback!
>>
>> I've made the following changes to my implementation :
>> - bounded channels with backpressure
>> - proper thread synchronization
>> - thread blocks that run on actual threads (unlike go blocks)
>>
>> TODO:
>> - alts!
>> - preserve thread local bindings in `go` blocks (`thread` too?)
>>
> --
> 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.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: functional implementation of core.async primitives

2017-11-12 Thread Timothy Baldridge
If you're looking for feedback, the input I gave on Reddit seems like a
good place to start (
https://www.reddit.com/r/Clojure/comments/7c0p3c/functional_implementation_of_coreasync/dpmvjpp/).
Like
I said, it's not really comparable to core.async at all, since it doesn't
properly support thread synchronization or back-pressure, and doesn't
implement any version of alts (aka select) or lightweight threads. It's a
fine implementation of threads busy waiting on immutable queues, but that
is a completely different thing than implementing the core.async primitives
or even a subset of CSP.



On Sun, Nov 12, 2017 at 3:05 PM, Jay Porcasi  wrote:

> wow looks so neat!
>
> i would be interested as well to know what experienced async users have to
> say
>
> Jay
>
> On Friday, November 10, 2017 at 1:32:52 PM UTC+7, Divyansh Prakash wrote:
>>
>>
>> Hi!
>>
>> I was messing around with Clojure and somehow ended up implementing a 
>> functional
>> core.async clone 
>> using a single threaded event loop.
>> By 'functional' I mean it is not macro based, unlike core.async.
>> It also fits into ~80 lines of sparse, documented code (check out
>> core.clj
>> 
>> )
>> I wanted to know if this approach is handicapped in some way?
>> I'm just learning, and my understanding might be way off base here.
>>
>> Thanks!
>> - Divyansh
>>
> --
> 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.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: hashmap keys

2017-11-09 Thread Timothy Baldridge
Most Clojure collections cache their hashcode, so that improves things
quite bit. Also, very large collections are rarely used as *keys* in other
maps. Most of the time key collections are one or two values. This means
that what we're really talking about is combining the hash values of a few
values, and that's pretty fast.

So sure, the initial hash of one million symbols inside a vector may take a
fair amount of time, but I've never seen that in the wild.

Timothy

On Thu, Nov 9, 2017 at 10:08 PM, Jay Porcasi  wrote:

> i would love to know in a bit more detail how Clojure manages to allow
> arbitrary data structures as keys for its immutable hashmaps
> hashing an atomic value as a string or number is fast and i see how that
> would work when atomic values are used as keys
> but how about using a big nested vector as a key? wouldn't hashing it take
> an unacceptable amount of time?
> yet Clojure manages to do just that and i wonder how
> thank you for any bit of clarification
> Jay
>
> --
> 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.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: Dynamically Reify Interfaces

2017-11-08 Thread Timothy Baldridge
Eval gets a bad reputation from languages like JS where it's messy and a
bit of a security risk. In Clojure, there's nothing wrong with using eval
for something like this.

On Tue, Nov 7, 2017 at 11:43 PM, Nick Mudge 
wrote:

> I need to dynamically reify some java interfaces based on data from a
> map.  One way I can see to do this is to generate the reify code with a
> function using syntax quotes, quotes and unquote and unquote splice.  And
> then evaluate it using eval. I hesitate using eval, but is eval the right
> tool for this case?
>
> Normally I would write a macro to generate code. A macro is good for
> generating code from source code. But in this case the data that is used to
> generate the code is coming from a var that holds a data structure.
>
> Any thoughts about when it is okay/good to use eval in Clojure?
>
>
>
> --
> 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.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: Who Uses import-vars?

2017-11-07 Thread Timothy Baldridge
I structure my code very explicitly. Normally the most common constructs
are put in a single file named after the library itself (not in core.clj,
do that half your files will be named core).

https://github.com/halgari/odin/blob/master/src/com/tbaldridge/odin.clj

Anything not in the API that should be unpublished to users is in other
namespaces that are imported and wrapped by vars in the main namespace.
This does several things:

* Keeps the public interface in one place
* Allows for a different public interface than the private one. Notice how
Odin has its own version of `when`, pulling that off require a bit of
careful macro usage, so I'd rather write that once under a different name,
then rename it to `when`.
* It's now simple to say "anything in this namespace is public and will not
change"

Core.async uses a pattern much like this, the API is in clojure.core.async,
most of the logic is under *.async.impl.*.

I don't recommend potemkin's import-vars at all. Clojure vars were not
meant to exist in more than one namespace at a time, so potemkin pulls of
its magic by linking two vars via watchers. This means that changes to one
var can cause side-effects in the other. In addition, bindings don't convey
properly (AFAIK), so if you using bindings on one var, the changes won't be
seen in the other var. Remember: import-vars doesn't actually import
anything, it simply creates a new var in the current namespace and links
the two via a two-way binding. It's quite the hack, imo.

So I have to agree with Potemkin's tagline on github: it's an idea that's
"almost good".

Timothy

On Tue, Nov 7, 2017 at 11:13 AM, Nick Mudge 
wrote:

> I am interested to know if people/you use import-vars to decouple the
> structure of code from its API.
>
> import-vars is from the potemkin library: https://github.com/ztellman/
> potemkin
>
> If you don't use import-vars how do you structure your code and provide an
> API?
>
>
> --
> 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.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: What's up with IMeta?

2017-11-01 Thread Timothy Baldridge
To start with, IObj and its .meta method are used with clojure.core/meta to
get the metadata on an object. Since this method can be the same between
refs and immutable data, they all use the same interface.

IMeta is used with withMeta and clojure.core/with-meta to return a new
object with the given metadata. Notice that:

(let [d {}]
  (identical? d (with-meta d {:some :meta}
; => false

IReference however has alterMeta which is used with
clojure.core/alter-meta, and as the name suggests it alters the metadata on
the object. It's a mutation of the object. This is needed with refs since
returning a new atom once you change the meta wouldn't be much help at all.

So there you have it, use with-meta for immutable objects, and alter-meta
for mutable objects.

Timothy

On Wed, Nov 1, 2017 at 7:20 PM, Didier  wrote:

> Hey, I was surprised to find that IMeta does not work for (with-meta).
>
> So it seems that withMeta is added to IObj, which extends IMeta. And it
> seems like alterMeta and resetMeta are added in IReference, which also
> extends IMeta.
>
> So now if you want to support meta, you have to implement IReference, IObj
> and IMeta?
>
> Is there a reason for this? Particularly, I find it strange I can't use
> with-meta on a Var, because it only implements IReference, and not IObj. So
> I can use all meta functions on Vars except for with-meta.
>
> Thank you.
>
> --
> 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.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: beginners' puzzle

2017-10-11 Thread Timothy Baldridge
Best answer for that is probably the source code itself:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Keyword.java

On Wed, Oct 11, 2017 at 9:07 AM,  wrote:

> how these keywords in clojure  implemented
> could  anyone anwer me ?
>
> --
> 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.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: About determinism of async

2017-10-11 Thread Timothy Baldridge
If you want to simply keep some messages in order, then a cat transducer
will do the trick just fine:


;; need a buffer or buffer size to get to the transducer param
(def c (chan 20 cat))

(async/onto-chan c [1])

(async/>!! c [2 3 4])
(async/close! c)

(
wrote:

> If you don't want to split at the consumer I would recommend adding
> another channel, and piping it with a cat xform as mentioned above.
>
> On Oct 11, 2017 3:28 AM, "JokkeB"  wrote:
>
>> Thanks. I'm not interested in reading the messages as pairs, I just need
>> to make sure nothing gets in between them. I think I'll choose some way to
>> merge the messages, for example just a vector like you suggested, and then
>> have the end consumer recognise and split the vector. I guess splitting the
>> vector into two messages somewhere before the end consumer can't be made
>> deterministic.
>>
>> keskiviikko 11. lokakuuta 2017 8.02.40 UTC+3 Rangel Spasov kirjoitti:
>>>
>>> I think simply wrapping the two values in a vector is the only thing
>>> that's needed in this case. Simply do a put like (>!! ch [my-val-1
>>> my-val-2]) and take from the channel from another place. If my-val-1 and
>>> my-val-2 are not immediately available, you can have a separate mechanism
>>> (atoms, (loop [...] (recur ...)) or another set of core.async channels
>>> perhaps) that "collects" them until they are ready to be sent together as
>>> one value.
>>>
>>> partition-all on its own does not really help with the ordering here.
>>> For example:
>>>
>>> (let [ch (chan 42 (partition-all 2))]
>>>   (>!! ch :x')
>>>   (thread   ;in another 
>>> thread far, far away
>>> (>> for random 0-99ms
>>> ;put value on ch
>>> (>!! ch :y'))
>>>
>>>   (>> for random 0-99ms
>>>   (>!! ch :x'')
>>>
>>>   ;take from ch
>>>   (>>
>>>
>>> This will non-deterministically output either
>>> => [:x' :x'']
>>>
>>> or
>>>
>>> => [:x' :y']
>>>
>>> But again as I said, you can employ partition-all separately as a
>>> "collecting" mechanism before doing the (>!! ch [my-val-1 my-val-2]).
>>> Didn't write an example for that but let me know if that's not clear and
>>> I can put together a few lines.
>>>
>>> On Tuesday, October 10, 2017 at 7:50:20 AM UTC-7, Gary Trakhman wrote:

 So, at the point where you need 2 things to be consecutive, wrap them
 up in a vector so they're one thing. `(partition-all 2)` will return a
 transducer xform that chunks up your message stream by 2
 https://clojuredocs.org/clojure.core/partition-all, and if you need to
 undo it you can do so with the `cat` transducer
 https://clojuredocs.org/clojure.core/cat .

 On Tue, Oct 10, 2017 at 10:42 AM JokkeB  wrote:

> Thanks for the response. That's what I suspected.
>
> How does partition help me in this case? I can't see any way of using
> it.
>
> How about onto-chan, would that be deterministic? Or any other
> function?
>
>
> tiistai 10. lokakuuta 2017 17.33.22 UTC+3 Gary Trakhman kirjoitti:
>
>> I think a core assumption is that all writes can yield control at any
>> time to other worker go processes.  I wouldn't rely on the consecutive
>> behavior even if it were true, nondeterminism is a good assumption with
>> core.async.  If you need that particular guarantee, consider a call to
>> partition?
>>
>> On Tue, Oct 10, 2017 at 10:30 AM JokkeB  wrote:
>>
> I'm wondering about a case when using async:
>>>
>>> I have a channel where I write from multiple threads. One of the
>>> sources is a go-loop with a timeout, so each second I write something to
>>> the channel. If I do two consecutive writes inside the go block, can
>>> another thread write between the two writes? Or can I rely on the two
>>> messages being consecutive in the channel?
>>>
>>> --
>>> 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 clo...@googlegroups.com

Re: Updating repeated nested structures?

2017-10-10 Thread Timothy Baldridge
My answer to most of these questions is often "write it once, stuff it in a
function, and forget about it".

Really though I often see this as a data-modeling and naming problem. For
example, you could go and write a `(update-cells cell-list f & args)` that
wraps custom logic for finding and manipulating cells.

In addition, think about ways to flatten the structure. It's a little hard
to figure out what you're trying to do here, but in general try to keep
data one or two layers deep, not only is it easier to manipulate, but it's
also easier to reason about. Once you get 3-4 layers deep in hashmaps, it
gets a bit messy, regardless of the tools you're using.



On Tue, Oct 10, 2017 at 2:18 PM, Rob Nikander 
wrote:

> Hi,
>
> Say I have a map like this:
>
> (def m {:qs [{:nums [3 1 2]} {:nums [7 4]}]})
>
> I want to transform each number with a function (say, `inc`). I imagine
> something like this:
>
> (update-in m [:qs * :cell-fns] #(map inc %))
> ; or
> (update-in m [:qs * :cell-fns *] inc)
>
>
> But of course you can't write that.  The following code works, but I don't
> like reading it:
>
> (update m :qs
> (fn [qs]
>   (mapv
> (fn [q]
>   (update q :nums #(mapv inc %)))
> qs)))
> => {:qs [{:nums [4 2 3]} {:nums [8 5]}]}
>
> Is there an idiomatic way to do this, that looks more like the shorter
> `update-in` idea?
>
> Rob
>
>
>
> --
> 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.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: Help with strange test output when deftest used inside a macro

2017-10-09 Thread Timothy Baldridge
The problem isn't the macro, it's your use of syntax quoting. `(= x y) gets
expanded at read-time into `(clojure.core/= x y)`. Not much you can do
about that. Although I'd suggest perhaps changing your code a bit to not
require macros.

deftest mostly just creates a defn with some extra metadata and the like.
One option would be to use a dynamic var to setup your config information.
Or better yet have the test itself read the config data the way your normal
app would. This not only exercises the same config codepaths, but it also
keeps the code quite functional.

On Mon, Oct 9, 2017 at 2:40 PM, Matt Grimm  wrote:

> Hello,
>
> I'm generating deftest's using a helper macro that takes a variety of test
> parameters and though the tests function correctly, the output of a failed
> test is not exactly right. The expect value is shown as the un-evaluated
> test form, and the actual value is shown as the result of evaluating the
> test form. I realize 'is' is a macro itself, but I'm not quite sure how to
> expand or escape the guts of my macro to make the output match that of a
> normal test.
>
> Whereas a normal test failure looks like this (some output elided):
>
> user=> (deftest normal-test
>   #_=>   (is (= [0 1 5] (range 3
> #'user/normal-test
> user=> (run-tests)
>
> FAIL in (normal-test)
>
> expected: [0 1 5]
>   actual: ((0 1 2))
>
> A failure for a deftest defined within a macro comes out like this:
>
> user=> (defmacro defnesttest [v]
>   #_=>   `(deftest nested-test
>   #_=>  (is (= [0 1 5] ~v
> #'user/defnesttest
> user=> (defnesttest (range 3))
> #'user/nested-test
> user=> (run-tests)
>
> FAIL in (nested-test)
>
> expected: (clojure.core/= [0 1 5] (range 3))
>   actual: false
>
> Thanks for any insight,
> m.
>
> --
> 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.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: Can slingshot/try+ and then catch Object really catch any error?

2017-10-08 Thread Timothy Baldridge
What REPL are you using? A rather nasty side-effect of NRepl is that it
tends to send messages from non-main-threads to weird places.

On Sun, Oct 8, 2017 at 10:29 PM,  wrote:

> I just re-wrote much of the code to run on the main thread. And so now I
> can see the error message (which was about a nil value in a place where I
> was certain there would be no nil values). Which is great. But since the
> app does a lot of I/O, I would like to for this app to be multi-threaded.
> But I need to figure out a way that I can see errors that happen in
> background threads.
>
>
> On Sunday, October 8, 2017 at 11:46:26 PM UTC-4, tbc++ wrote:
>>
>> I don't think you can catch an Object on the JVM can you? What happens if
>> you catch Throwable?
>>
>> On Sun, Oct 8, 2017 at 9:43 PM,  wrote:
>>
>>> So, for instance, this says that 10 documents were retried:
>>>
>>> {"message" {:num-slabs 1, :num-active-slabs 1, :enqueued 389, :retried
>>> 10, :completed 378, :in-progress 1}}
>>>
>>> The only place that I call retry! is in this catch block (this function
>>> runs in a background thread):
>>>
>>> (defn advance
>>>   [message]
>>>   {:pre [
>>>  (= (type message) durable_queue.Task)
>>>  ]}
>>>   (slingshot/try+
>>>(doseq [[k v] @message]
>>>  (when-not (or
>>> (= :how-many-rows-and-fields-from-database k)
>>> (= :database-table k)
>>> (= :denormalized-id k)
>>> (= :topic k))
>>>(transform
>>> (get @message :denormalized-id :missing-denormalized-id)
>>> k
>>> v
>>> (get @message :topic :missing-topic)
>>> (get @message :how-many-rows-and-fields-from-database
>>> :missing-how-many-rows-and-fields-from-database
>>>
>>>(durable/complete! message)
>>>(catch Object o
>>>  (durable/retry! message)
>>>  (slingshot/throw+ {
>>> :type ::advance
>>> :error o
>>> }
>>>
>>>
>>> So clearly, the code has a problem with some of the documents, and so an
>>> error is thrown, and it is caught by the catch block. I would love to see
>>> the error. I can not. If I put println in the catch block, the message
>>> never shows up in the terminal. Likewise if I use Timbre.
>>>
>>> I would love to see the error object. My inability to see the error
>>> objects has crippled my productivity.
>>>
>>> Can anyone tell me what I need to do to see these errors?
>>>
>>>
>>>
>>>
>>>
>>> On Sunday, October 8, 2017 at 11:13:10 PM UTC-4, lawrence...@gmail.com
>>> wrote:
>>>
 I'm trying to use a Zach Tellman's durable-queue to pass information
 from one part of my app to another. I have 3 queues. I also have a function
 that runs every 30 seconds, that is suppose to report some statistics for
 me:

   (fn []
 (future
   (slingshot/try+
(errors/log "Resource usage: "
(monitoring/show-stats-regard
 ing-resources-used-by-this-app))
(errors/log "Stats about from-mysql-to-tables-queue:
 " (durable/stats from-mysql-to-tables-queue))
(errors/log "Stats about
 from-tables-to-topics-queue: " (durable/stats from-tables-to-topics-queue))
(errors/log "Stats about the
 from-topics-to-persistence-queue: " (durable/stats
 from-topics-to-persistence-queue))
(catch Object o
  (slingshot/throw+ {
 :type
 ::cycle-resource-usage-report
 :error o
 }
)

 I think there is an error here, because I see the first (errors/log)
 but typically not anything after that. Can I rely on the fact that this
 should catch anything:

(catch Object o

 Because it doesn't seem to work. Instead, the app runs for 8 minutes,
 then prints data about the queues just once, then never again. Assuming an
 error is occuring, why can't I see the error?


 {:timestamp "17-10-09 01:27:45", :level :trace, :hostname
 "ip-172-31-4-54", :message ("STARTING")}

 Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new
 driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically
 registered via the SPI and manual loading of the driver class is generally
 unnecessary.


 {:timestamp "17-10-09 01:28:16", :level :trace, :hostname
 "ip-172-31-4-54", :message ("\n\n\n\n\nResource usage: " "Memory in use
 (percentage/used/max-heap): (\"67%\" \"2414M\" \"3568M\")\n\nCPU usage
 (how-many-cpu's/load-average):  [4 1.56]\n\nFree 

Re: Can slingshot/try+ and then catch Object really catch any error?

2017-10-08 Thread Timothy Baldridge
I don't think you can catch an Object on the JVM can you? What happens if
you catch Throwable?

On Sun, Oct 8, 2017 at 9:43 PM,  wrote:

> So, for instance, this says that 10 documents were retried:
>
> {"message" {:num-slabs 1, :num-active-slabs 1, :enqueued 389, :retried 10,
> :completed 378, :in-progress 1}}
>
> The only place that I call retry! is in this catch block (this function
> runs in a background thread):
>
> (defn advance
>   [message]
>   {:pre [
>  (= (type message) durable_queue.Task)
>  ]}
>   (slingshot/try+
>(doseq [[k v] @message]
>  (when-not (or
> (= :how-many-rows-and-fields-from-database k)
> (= :database-table k)
> (= :denormalized-id k)
> (= :topic k))
>(transform
> (get @message :denormalized-id :missing-denormalized-id)
> k
> v
> (get @message :topic :missing-topic)
> (get @message :how-many-rows-and-fields-from-database
> :missing-how-many-rows-and-fields-from-database
>
>(durable/complete! message)
>(catch Object o
>  (durable/retry! message)
>  (slingshot/throw+ {
> :type ::advance
> :error o
> }
>
>
> So clearly, the code has a problem with some of the documents, and so an
> error is thrown, and it is caught by the catch block. I would love to see
> the error. I can not. If I put println in the catch block, the message
> never shows up in the terminal. Likewise if I use Timbre.
>
> I would love to see the error object. My inability to see the error
> objects has crippled my productivity.
>
> Can anyone tell me what I need to do to see these errors?
>
>
>
>
>
> On Sunday, October 8, 2017 at 11:13:10 PM UTC-4, lawrence...@gmail.com
> wrote:
>
>> I'm trying to use a Zach Tellman's durable-queue to pass information from
>> one part of my app to another. I have 3 queues. I also have a function that
>> runs every 30 seconds, that is suppose to report some statistics for me:
>>
>>   (fn []
>> (future
>>   (slingshot/try+
>>(errors/log "Resource usage: "
>>(monitoring/show-stats-regard
>> ing-resources-used-by-this-app))
>>(errors/log "Stats about from-mysql-to-tables-queue: "
>> (durable/stats from-mysql-to-tables-queue))
>>(errors/log "Stats about from-tables-to-topics-queue:
>> " (durable/stats from-tables-to-topics-queue))
>>(errors/log "Stats about the
>> from-topics-to-persistence-queue: " (durable/stats
>> from-topics-to-persistence-queue))
>>(catch Object o
>>  (slingshot/throw+ {
>> :type
>> ::cycle-resource-usage-report
>> :error o
>> }
>>)
>>
>> I think there is an error here, because I see the first (errors/log) but
>> typically not anything after that. Can I rely on the fact that this should
>> catch anything:
>>
>>(catch Object o
>>
>> Because it doesn't seem to work. Instead, the app runs for 8 minutes,
>> then prints data about the queues just once, then never again. Assuming an
>> error is occuring, why can't I see the error?
>>
>>
>> {:timestamp "17-10-09 01:27:45", :level :trace, :hostname
>> "ip-172-31-4-54", :message ("STARTING")}
>>
>> Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver
>> class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered
>> via the SPI and manual loading of the driver class is generally unnecessary.
>>
>>
>> {:timestamp "17-10-09 01:28:16", :level :trace, :hostname
>> "ip-172-31-4-54", :message ("\n\n\n\n\nResource usage: " "Memory in use
>> (percentage/used/max-heap): (\"67%\" \"2414M\" \"3568M\")\n\nCPU usage
>> (how-many-cpu's/load-average):  [4 1.56]\n\nFree memory in jvm:
>> [1201758848]")}
>>
>>
>> {:timestamp "17-10-09 01:28:49", :level :trace, :hostname
>> "ip-172-31-4-54", :message ("\n\n\n\n\nResource usage: " "Memory in use
>> (percentage/used/max-heap): (\"81%\" \"2900M\" \"3568M\")\n\nCPU usage
>> (how-many-cpu's/load-average):  [4 2.64]\n\nFree memory in jvm:
>> [699798216]")}
>>
>> ;; removing redundant entries
>>
>> {:timestamp "17-10-09 01:34:48", :level :trace, :hostname "UnknownHost",
>> :message ("\n\n\n\n\nResource usage: " "Memory in use
>> (percentage/used/max-heap): (\"87%\" \"3118M\" \"3568M\")\n\nCPU usage
>> (how-many-cpu's/load-average):  [4 3.77]\n\nFree memory in jvm:
>> [471249616]")}
>>
>>
>> {:timestamp "17-10-09 01:35:17", :level :trace, :hostname
>> "ip-172-31-4-54", :message ("\n\n\n\n\nResource usage: " "Memory in use
>> (percentage/used/max-heap): (\"87%\" \"3120M\" \"3568M\")\n\nCPU usage
>> 

Re: Using memory with futures

2017-09-05 Thread Timothy Baldridge
Every thread created on the JVM takes about 2MB of memory. Multiply that by
that number of threads, and I'm surprised your memory usage is that low.
But the futures thread pool will also re-use previously created threads for
new futures. In order to optimize this, a certain number of threads will be
kept around for some time incase they need to be reused. In my limited
testing it takes about a minute for the pool to decide to shutdown the
threads.

On top of all that, you're measuring the JVM memory usage through Window's
task manager, from what I can tell. Internally the JVM may be using way
less memory, but it hasn't bothered to give that back to the OS yet because
it guesses that if you used this much memory in the past, you may use that
amount again soon. In certain configurations, the JVM may never give the
memory back the OS. So if you want accurate memory usage stats you should
use a tool that can look into the internals of the JVM, or perhaps use some
of the GC stats you can access via the Runtime class.

On Tue, Sep 5, 2017 at 2:14 PM, Max Muranov  wrote:

> Hello! I've read in this
>  thread that
> futures are garbage collected and it's okay to use them for side effects.
> But what about such program?
>
> (dotimes [n 10]
>   (future (Thread/sleep 1000)))
>
> After performing the code several times I see this in my task manager:
>
>
> After each performing the amount of using memory increases. So how can I
> use futures to free the memory after they were finished?
>
> --
> 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.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: SRSLY? (= (true? identity) (false? identity)) => true

2017-09-01 Thread Timothy Baldridge
Think about what you're asking:

"Hey, is identity a boolean true value?"

"No, it is a function, not a boolean"


"Is, identity a boolean false value?"

"No, it's a function, not a boolean"


Makes plenty sense to me.


On Fri, Sep 1, 2017 at 10:06 PM, Rostislav Svoboda <
rostislav.svob...@gmail.com> wrote:

> > identity isn't a boolean, so neither true? nor false? should return true
> for it
>
> But then why it should return 'false'?
>
> 2017-09-02 6:04 GMT+02:00 Justin Smith :
> > identity isn't a boolean, so neither true? nor false? should return true
> for
> > it
> >
> >
> > On Fri, Sep 1, 2017 at 9:01 PM Rostislav Svoboda
> >  wrote:
> >>
> >> > (true? identity) -> false
> >> > (false? identity) -> false
> >> > (= false false) -> true
> >>
> >> Well:
> >> (= identity identity) -> true
> >>
> >> My math books say booleans can't be true and false in the same time.
> >>
> >> --
> >> 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.
>
> --
> 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.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: core.async got in a bad state?

2017-08-29 Thread Timothy Baldridge
To add to what Alex said, look at this trace:
https://gist.github.com/anonymous/65049ffdd37d43df8f23630928e8fed0#file-thread-dump-out-L1337-L1372

Here we see a go block calling mapcat, and inside the inner map something
is calling >!!. As Alex mentioned this can be a source of deadlocks. No
code called by a go block should ever call the blocking variants of
core.async functions (!!, alts!!, etc.). So I'd start at the code
redacted in those lines and go from there.



On Tue, Aug 29, 2017 at 11:09 AM, Alex Miller  wrote:

> go blocks are multiplexed over a thread pool which has (by default) 8
> threads. You should never perform any kind of blocking activity inside a go
> block, because if every go block in work happens to end up blocked, you
> will prevent all go blocks from making any further progress. It sounds to
> me like that's what has happened here. The go block threads are named
> "async-dispatch-" and it looks like there are 8 blocked ones in your
> thread dump.
>
> It also looks like they are all blocking on a >!!, which is a blocking
> call. So I would look for a go block that contains a >!! and convert that
> to a >! or do something else to avoid blocking there.
>
>
> On Tuesday, August 29, 2017 at 11:48:25 AM UTC-5, Aaron Iba wrote:
>>
>> My company has a production system that uses core.async extensively.
>> We've been running it 24/7 for over a year with occasional restarts to
>> update things and add features, and so far core.async has been working
>> great.
>>
>> The other day, during a particularly high workload, the whole system got
>> locked up. All the channels seemed blocked at once.  I was able to connect
>> with a REPL and poke around, and noticed strange behavior of core.async.
>> Specifically, the following code, when evaluated in the REPL, blocked on
>> the put (third expression):
>>
>> (def c (async/chan))
>> (go-loop []
>>   (when-some [x (> (println x)
>> (recur)))
>> (>!! c true)
>>
>> Whereas on any fresh system, the above expressions obviously succeed.
>>
>> Puts succeeded if they went onto the channel's buffer, but not when they
>> should go through to a consumer. For example with the following
>> expressions, evaluated in the REPL, the first put succeeded (presumably
>> because it went on the buffer), but subsequent puts blocked:
>>
>> (def c (async/chan 1))
>> (def m (async/mult c))
>> (def out (async/chan (async/sliding-buffer 3)))
>> (async/tap m out)
>> (>!! c true) ;; succeeds
>> (>!! c true) ;; blocks forever
>>
>> This leads me to wonder if core.async itself somehow got into a bad
>> state. It's entirely possible I caused this by misusing the API somewhere
>> in the codebase, but we use core.async so extensively that I wouldn't know
>> where to begin looking.
>>
>> I'm wondering if someone more familiar with core.async internals has an
>> idea about what could cause the above situation. Or if we notice it
>> happening again, what could I do to gather more helpful information.
>>
>> I also have a redacted thread dump, in case it's useful:
>>
>> https://gist.github.com/anonymous/65049ffdd37d43df8f23630928e8fed0
>>
>> Any help would be much appreciated,
>>
>> Aaron
>>
>> P.S. core.async has been a godsend in terms of helping us structure and
>> modularize our large system.  Thank you to all those who contributed to
>> this wonderful library!
>>
>> --
> 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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-28 Thread Timothy Baldridge
>>  https://github.com/arrdem/guten-tag

The name alone deserves a +1. :D


On Mon, Aug 28, 2017 at 2:53 PM, Reid McKenzie  wrote:

> FWIW I wrote a library around defining tagged map types
> https://github.com/arrdem/guten-tag and used it heavily in the Grimoire
> implementation almost entirely to my satisfaction. No idea if anyone else
> ever picked it up, and due to implementation details of Clojure's let map
> destructuring you can't just treat one of my map wrapper types as a normal
> Clojure map and :keys it apart but it works great with core.match.
>
> Reid
>
> On Friday, August 25, 2017 at 1:30:37 PM UTC-7, tbc++ wrote:
>>
>> >> they're a little nicer to type and read
>>
>> And that's where I have to disagree. The problem with most of these
>> options is they complect ordering with meaning.
>>
>> [:image/file "/images/image" :jpeg]
>>
>> Here I have no idea what these values mean. I have to have out-of-band
>> information about what offset in the vector corresponds to what value.
>> Functions have this same problem, look no further than `cons` vs `conj` to
>> see potential confusion on argument ordering.
>>
>> So why don't we only use maps for function arguments? Well mostly to make
>> the functions easier to manipulate by humans. But some of the best
>> libraries for web APIs (AWS) that I've used have used almost an exclusively
>> map based interface.
>>
>> Once again I have to repeat my mantra about DSLs. Don't start with DSLs.
>> Start with maps. Build everything off of maps. They're extensible, easy to
>> introspect, and can drive a host of metaprogramming algorithms. If maps are
>> to hard to understand, build constructor functions on top of them. Then
>> finally build a DSL on top, if you need it.
>>
>> Frankly, I have so many things I have to remember during programming. I'd
>> much rather see a very uniform map-based interface. Than any sort of nested
>> vectors, tagged values, or anything else.
>>
>> Surely we can't say that this:
>> >> [[:image/file :image/web] :image.file/path "/images/image"
>> :image.file/format :jpeg :image.web/url "www.myimage.com/image"]
>>
>> Is a better interface than:
>>
>> {:image.file/path "/images/image"
>>  :image.file/format :jpeg
>>  :image.web/url "www.myimage.com/image"}
>>
>> And as I said before, spec is designed from the start to support data in
>> this format. Stating "this is a file", "this is a web image". Is just book
>> keeping that doesn't need to be done. Is a map a :image/web? Well check its
>> members and see if they match the spec. If they match, then you have a
>> :image/web. No need for sum types, tags, wrapping values in vectors. Simply
>> state what a thing should have for it to conform to an interface, and
>> forget whatever else might be in there. It couldn't be simpler.
>>
>> On Fri, Aug 25, 2017 at 11:59 AM, Didier  wrote:
>>
>>> Thanks for everyone's great input.
>>>
>>> Currently, I see the big distinction being concise vs extension. Maybe
>>> for streaming variants would be better as the format would be smaller to
>>> transfer over a wire. And for small short lived programs, or things you
>>> know won't need extension, variants offer a slightly more convenient
>>> structure to work with.
>>>
>>> I think both can be specced easily. S/or a few s/tuple to spec a
>>> variant. And multi-spec over a set for the map version.
>>>
>>> I'd like to explore then the issue of extensibility with variants. How
>>> would you extend them, is there really no way? This is some of my
>>> brainstorming thoughts.
>>>
>>> 1) How to design a variant of more then one value?
>>>
>>>
>>> 1.1)
>>>
>>> I know this is a standard variant of one value:
>>>
>>> [:image/web "www.myimage.com/image.jpg"]
>>>
>>> I believe to extend it to more values, you would do:
>>>
>>> [:image/file "/images/image" :jpeg]
>>>
>>> That is, you'd threat it as a constructor function, which creates an
>>> :image/file type and takes an ordered list of arguments. This way, each
>>> variant type can even be overloaded on their arguments the way you'd
>>> overload a function.
>>>
>>> [:image/file "/images/image"]
>>>
>>> Can default to format :png for example, when using the one arg
>>> constructor.
>>>
>>> 1.2)
>>>
>>> An alternative is to keep variants as vector pairs, and nest them.
>>>
>>> [:image/file [:image/file-path "/images/image"]
>>> [:image/file-format:jpeg]]
>>>
>>> In this form, variants are more like their map counterpart. Each element
>>> is named and itself a variant.
>>>
>>> 1.3)
>>>
>>> You could also decide to limit variants to strict pairs, so the second
>>> element of any variant is either a variant or a vector of variants.
>>>
>>> [:image/file [[:image/file-path "/images/image"]
>>> [:image/file-format:jpeg]]]
>>>
>>> Now with both these forms, 1.2 and 1.3, if you threat them again as
>>> constructor functions, you now have a form of named parameter on your
>>> constructor, allowing mixed order.
>>>
>>> 1.4)
>>>
>>> At this point, 

Re: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-25 Thread Timothy Baldridge
>> they're a little nicer to type and read

And that's where I have to disagree. The problem with most of these options
is they complect ordering with meaning.

[:image/file "/images/image" :jpeg]

Here I have no idea what these values mean. I have to have out-of-band
information about what offset in the vector corresponds to what value.
Functions have this same problem, look no further than `cons` vs `conj` to
see potential confusion on argument ordering.

So why don't we only use maps for function arguments? Well mostly to make
the functions easier to manipulate by humans. But some of the best
libraries for web APIs (AWS) that I've used have used almost an exclusively
map based interface.

Once again I have to repeat my mantra about DSLs. Don't start with DSLs.
Start with maps. Build everything off of maps. They're extensible, easy to
introspect, and can drive a host of metaprogramming algorithms. If maps are
to hard to understand, build constructor functions on top of them. Then
finally build a DSL on top, if you need it.

Frankly, I have so many things I have to remember during programming. I'd
much rather see a very uniform map-based interface. Than any sort of nested
vectors, tagged values, or anything else.

Surely we can't say that this:
>> [[:image/file :image/web] :image.file/path "/images/image"
:image.file/format :jpeg :image.web/url "www.myimage.com/image"]

Is a better interface than:

{:image.file/path "/images/image"
 :image.file/format :jpeg
 :image.web/url "www.myimage.com/image"}

And as I said before, spec is designed from the start to support data in
this format. Stating "this is a file", "this is a web image". Is just book
keeping that doesn't need to be done. Is a map a :image/web? Well check its
members and see if they match the spec. If they match, then you have a
:image/web. No need for sum types, tags, wrapping values in vectors. Simply
state what a thing should have for it to conform to an interface, and
forget whatever else might be in there. It couldn't be simpler.

On Fri, Aug 25, 2017 at 11:59 AM, Didier  wrote:

> Thanks for everyone's great input.
>
> Currently, I see the big distinction being concise vs extension. Maybe for
> streaming variants would be better as the format would be smaller to
> transfer over a wire. And for small short lived programs, or things you
> know won't need extension, variants offer a slightly more convenient
> structure to work with.
>
> I think both can be specced easily. S/or a few s/tuple to spec a variant.
> And multi-spec over a set for the map version.
>
> I'd like to explore then the issue of extensibility with variants. How
> would you extend them, is there really no way? This is some of my
> brainstorming thoughts.
>
> 1) How to design a variant of more then one value?
>
>
> 1.1)
>
> I know this is a standard variant of one value:
>
> [:image/web "www.myimage.com/image.jpg"]
>
> I believe to extend it to more values, you would do:
>
> [:image/file "/images/image" :jpeg]
>
> That is, you'd threat it as a constructor function, which creates an
> :image/file type and takes an ordered list of arguments. This way, each
> variant type can even be overloaded on their arguments the way you'd
> overload a function.
>
> [:image/file "/images/image"]
>
> Can default to format :png for example, when using the one arg constructor.
>
> 1.2)
>
> An alternative is to keep variants as vector pairs, and nest them.
>
> [:image/file [:image/file-path "/images/image"] [:image/file-format:jpeg]]
>
> In this form, variants are more like their map counterpart. Each element
> is named and itself a variant.
>
> 1.3)
>
> You could also decide to limit variants to strict pairs, so the second
> element of any variant is either a variant or a vector of variants.
>
> [:image/file [[:image/file-path "/images/image"]
> [:image/file-format:jpeg]]]
>
> Now with both these forms, 1.2 and 1.3, if you threat them again as
> constructor functions, you now have a form of named parameter on your
> constructor, allowing mixed order.
>
> 1.4)
>
> At this point, the variant has become pretty similar to a map, losing in
> verbosity over it even. There's just one advantage, the type is not a
> key/value pair, which I find is more intuitive to use, no need to know the
> special name of key that holds the type.
>
> 1.5)
>
> Let's try to make it concise again.
>
> [:image/file {:image/file-path "/images/image" :image/format :jpeg}]
>
> This hybrid avoids needing a type key, while having named parameters, its
> the best of both worlds, but it mixes vectors and maps.
>
> 1.6)
>
> Here it is with the lispcast suggestion:
>
> {:image/file {:image/file-path "/images/image" :image/format :jpeg}}
>
> What I don't like about this, is how do you group variants together? Do
> you add more to this map? Do you keep each variant a map of one key and
> group them on a vector?
>
> It does solve the problem of wanting to pass a vector to your variant
> though, as the lispcast 

Re: CPU & platform for best compilation performance

2017-08-23 Thread Timothy Baldridge
"My codebase (mix of CLJ, CLJS and CLJS) is about fifty thousand lines of
code, and compilation times are starting to interfere with my workflow
happiness. In addition, Chrome Devtools is becoming somewhat sluggish due
to the high number of separate namespaces loaded through Figwheel."

That's not an insane codebase size, but I wonder what your actual
compilation times are? Honesty, I'd be surprised if you even got a 20%
speedup in a compiler by simply upgrading the CPU. CPU tech improvements
are more often focused around numerical computing and vector optimizations.
When there are massive leaps forward in raw execution performance, they're
often less than 20%.

So perf numbers are important here. Also if figwheel is loading large
namespaces into the browser, and running a lot of hooks to patch up the
running system, that can also affect performance.

I'd recommend taking a look the CLJS code in a profiler and seeing where
the slowdown is. Perhaps the namespaces are too large and figwheel is
sending across megabytes of JS, or perhaps there's a bad algorithm
somewhere.

On Wed, Aug 23, 2017 at 9:54 AM, Maarten Truyens <
maarten.truy...@siteffects.be> wrote:

> Hi all,
>
> My codebase (mix of CLJ, CLJS and CLJS) is about fifty thousand lines of
> code, and compilation times are starting to interfere with my workflow
> happiness. In addition, Chrome Devtools is becoming somewhat sluggish due
> to the high number of separate namespaces loaded through Figwheel.
>
> My current machine is a 6-core Mac Pro 3.5 Ghz Xeon ("late 2013"). For
> quite a while I have been investigating whether a switch to another machine
> and/or platform would be interesting from a workflow speed point of view.
> However, aside from Timothy Pratley's article on the AMD Ryzen 1800x (
> http://timothypratley.blogspot.in/2017/03/ryzen-is-for-programmers.html),
> I have trouble finding information that is relevant for us Clojure
> programmers.
>
> I would summarize my research as follows:
> * single-core performance is most important, so that it is probably the
> case that a 4-core CPU with a higher single-thread speed is preferable to
> an 6/8/10-core CPU with a slower single-thread speed;
> * as from 4 cores, there are hardly any speedups to be expected for having
> more cores in CLJ or even (parallel) CLJS builds;
> * the Ryzens are great value, but their single-core performance is usually
> 10-20% below the top of the line Intels;
> * according to the many Phoronix benchmarks, Linux and OSX have about the
> same performance, although there are some interesting deviations for some
> workflows (even up to 30 - 40%);
> * the single-core performance difference between my current CPU and the
> single-core top of the line (i7700K, i7-7800X or i7-7820X) seems to be
> between 20-40%
>
> While a 50% performance increase would be enough to warrant the time
> investment & cost of switching, my fear is that the real-world speed-up
> will probably be more like a meager 20%.
>
> Ignoring cost considerations and performance outside CLJ development: what
> CPU and platform would you recommend?
>
> Many thanks!
>
> Maarten
>
> --
> 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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
Simple: because failing to put it in a map constrains future growth.

Putting things into a set restricts you to unique values. Putting values
into a vector constrains you to a specific ordering. And quite frankly one
little mistake like this can cause tons of refactoring down the road.
Better to write it once, simply, and extensible.

I can't tell you how many codebases I've worked on where they failed to
allow for "extra data" in either the arguments or the return of a function
or endpoint and we've had to do major refactoring once a single part of the
system needs a configuration flag.

But I guess I'd flip it around. Why would I ever want:

[:response val]

when I could have

{:status :response
 :result val}

The latter is more readable, self-documenting, and extensible. I can't
think of a single design benefit the variant variant has over the map.

On Tue, Aug 22, 2017 at 9:43 PM, James Reeves <ja...@booleanknot.com> wrote:

> On 23 August 2017 at 03:58, Timothy Baldridge <tbaldri...@gmail.com>
> wrote:
>
>> Put let's take that and look at it under a engineering lens a bit:
>>
>> >> For example, a series of events that represent a player's moves in a
>> card game:
>> >>
>> >>  [:card/draw :9h]
>>
>> You have an ad-hoc encoding of data here now. Expand it out a bit, and
>> make it machine readable instead of preferring ease of writing and you get:
>>
>> {:player/action :card/draw
>>  :card/number :9
>>  :card/suit :hearts}
>>
>> Much easier to introspect, and extensible as future data just flows
>> through without existing code breaking because you add extra data.
>>
>
> But possibly over-engineered. Suppose that the only function we want to
> produce is:
>
>   (cards-in-hand events)
>   => #{:9h :qh :7d}
>
> If we have a function that returns [k], [v] or {k v}, then I have a hard
> time buying the idea that the input to the function should be more complex
> than [[k v]].
>
> If the scope of the data is not so constrained, then sure, use a map.
>
> >> I've also found it a useful pattern for data access:
>> >>
>> >>  [:data/found "Bob"]
>>
>> I've worked with systems that have done this, and I really dislike it.
>> Because now I have to zip the inputs of a function with the outputs if I
>> want a composable system usable in pipelines and the like.
>>
>> What's much better:
>>
>> {:op/status :success
>>  :data/found "Bob"
>>  :data/key "444-434-3323"
>>  :server/ip }
>>
>> Now not only do I know what data I got, but where it came from, the key I
>> originally used, etc.
>>
>
> Which is useful only if you plan on using that additional data. If you are
> only ever interested in the key and value, and the function is internal,
> why dress it up?
>
> --
> James Reeves
> booleanknot.com
>
> --
> 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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
But Datomic has E in [e a v] which links multiple [a v] pairs into an
entity...which is basically a map. So I don't think that applies here.

  GET /example HTTP/1.1
  Host: www.example.com

  [:request/method :get]
  [:request/uri "/example"]
  [:request/protocol "HTTP/1.1"]
  [:request/header ["host" "www.example.com"]]

Once again, a ad-hoc encoding. What is "GET", what is "/example". I see
that datastructure and all I see are hashmaps.

Do it the way ring does ;-)

{:method :get
 :uri "..."
 :headers [...]}



On Tue, Aug 22, 2017 at 9:14 PM, James Reeves  wrote:

> On 23 August 2017 at 03:48, Didier  wrote:
>
>> I can see it be quick and concise for representing events, but that's
>> also exactly the use case example for multi-spec: https://clojure.or
>> g/guides/spec#_multi_spec
>>
>> What happens if your event needs more data? Maybe draw needs 2
>> attributes, the card and the deck? Now you have implicit encoding, where
>> what the attributes are for the event are defined by its position in the
>> vector.
>>
>
> Sometimes it's an advantage to have a deliberately constrained format,
> particularly when it comes to storage or indexing. Datomic, for instance,
> is effectively an indexed event log of [e a v t] tuples.
>
> If you're in a situation where the event data can and may expand, then use
> a map. But I'd argue that there are situations where the scope is limited,
> or you want a deliberate and hard constraint on what data is in an event.
>
> Another possible situation is if you're parsing map data incrementally.
> For example, a Ring request map could be read in as a series of key/value
> pairs:
>
>   GET /example HTTP/1.1
>   Host: www.example.com
>
>   [:request/method :get]
>   [:request/uri "/example"]
>   [:request/protocol "HTTP/1.1"]
>   [:request/header ["host" "www.example.com"]]
>
> I'm not saying that variants should be favoured over maps in all
> situations; just that there are situations where you're certain that you
> need key/value pairings.
>
> --
> James Reeves
> booleanknot.com
>
> --
> 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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
Put let's take that and look at it under a engineering lens a bit:

>> For example, a series of events that represent a player's moves in a
card game:
>>
>>  [:card/draw :9h]

You have an ad-hoc encoding of data here now. Expand it out a bit, and make
it machine readable instead of preferring ease of writing and you get:

{:player/action :card/draw
 :card/number :9
 :card/suit :hearts}

Much easier to introspect, and extensible as future data just flows through
without existing code breaking because you add extra data.

Likewise:

>> I've also found it a useful pattern for data access:
>>
>>  [:data/found "Bob"]

I've worked with systems that have done this, and I really dislike it.
Because now I have to zip the inputs of a function with the outputs if I
want a composable system usable in pipelines and the like.

What's much better:

{:op/status :success
 :data/found "Bob"
 :data/key "444-434-3323"
 :server/ip }

Now not only do I know what data I got, but where it came from, the key I
originally used, etc.

>>   [:data/retry-in 600]

If this is a web endpoint, I'd really like a URL with it:

{:op/status :busy
 :retry/delay 600
 :retry/url #url "http://"}

In short variants almost never give me enough information, and when they
do, it's encoded in some sort of DSL that I have to parse or enrich if I
want nice machine level introspection.

On Tue, Aug 22, 2017 at 8:48 PM, Didier <didi...@gmail.com> wrote:

> I can see it be quick and concise for representing events, but that's also
> exactly the use case example for multi-spec: https://clojure.
> org/guides/spec#_multi_spec
>
> What happens if your event needs more data? Maybe draw needs 2 attributes,
> the card and the deck? Now you have implicit encoding, where what the
> attributes are for the event are defined by its position in the vector.
>
> Where as you could have just as easily had:
>
> {:event/type :draw :card :4s :deck :player1}
>
> You can make a vector of those for the order of the events.
>
> Yes, you can also use variants, and have:
>
> [:event/draw :4s :player1]
>
> My question is, what's the pros/cons? Its more concise, but barely. Its
> harder for it to represent optional values, you have to allow nil:
> [:event/draw :4s nil]. You can mistake the order: [:event/draw :player1
> :4s].
>
> I think to represent the type of a single element, I agree with you, but
> if you've got a compound type, at first glance, they'd appear less
> practical and more error prone to me. So your second example makes more
> sense.
>
>
> On Tuesday, 22 August 2017 19:07:56 UTC-7, James Reeves wrote:
>
>> On 23 August 2017 at 01:18, Timothy Baldridge <tbald...@gmail.com> wrote:
>>
>>> Great, so these approaches are suggesting we wrap every value in a
>>> vector or a hash map (as the lisp cast article does).
>>>
>>
>> What? No, that's not what I'm saying at all.
>>
>> If you have an unordered collection of key/value pairs where every key is
>> unique, then *of course* you use a map.
>>
>> But if you have only *one* key/value pair, how do you represent that? Or
>> if you want an arbitrarily ordered collection of key/value pairs? Or a
>> collection with repetition?
>>
>> For example, a series of events that represent a player's moves in a card
>> game:
>>
>>   [:card/draw :9h]
>>   [:card/draw :qh]
>>   [:card/draw :4s]
>>   [:card/discard :4s]
>>   [:card/draw :7d]
>>
>> I've also found it a useful pattern for data access:
>>
>>   [:data/found "Bob"]
>>   [:data/not-found]
>>   [:data/unauthorized]
>>   [:data/retry-in 600]
>>
>> A [k v] vector isn't the only way of representing data like this, but it
>> is probably the most concise.
>>
>> --
>> James Reeves
>> booleanknot.com
>>
> --
> 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–lac

Re: Sum types in Clojure? Better to represent as tagged records or asvariant vectors?

2017-08-22 Thread Timothy Baldridge
I think that's true, but even back in 2015, these were the only two sources
calling for this approach, and it never really caught on. I even did some
experiments with it, but my conclusion was that it was more trouble than it
was worth.

On Tue, Aug 22, 2017 at 7:46 PM, Sean Corfield <s...@corfield.org> wrote:

> I think part of the issue is that the article dates back to mid-2015 and
> `clojure.spec` wasn’t a thing back then, was it?
>
>
>
> Variants feel like a solution to a problem for which we have a much better
> solution _*today*_ than we did two years ago. The article talks about
> using core.typed and core.match with variants – because that’s what we had
> then. I’m fairly sure that if Eric (and Jeanine) were writing their
> material today, we’d see `clojure.spec` front and center and regular hash
> maps being used.
>
>
>
> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>
>
> *From: *Timothy Baldridge <tbaldri...@gmail.com>
> *Sent: *Tuesday, August 22, 2017 6:00 PM
> *To: *clojure@googlegroups.com
> *Subject: *Re: Sum types in Clojure? Better to represent as tagged
> records or asvariant vectors?
>
>
>
> I think the article is a bit misleading. Variants were never that popular
> in Clojure. Infact I've never seen them used in production code or the most
> common Clojure libraries. So I'm a bit perplexed as to why the article
> recommends them so strongly.
>
>
>
> So I think the answer is, they are a fun thought experiment in Clojure,
> but are of limited usefulness due to the tools we have available that make
> them unneeded.
>
>
>
> It's a bit like recommending that new users use actors in Clojure. Sure,
> you can shoehorn them in, but there's a reason why they aren't the default.
>
> --
>
> “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.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.
>



-- 
“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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
Nope, ClojureScript uses nested hash maps (try it for yourself here:
http://vps124502.vps.ovh.ca/rage/resources/public/). As does tools.analyer.
Instaparse and Hiccup use a variant of variants, but funny enough the first
thing I ever do when writing code with instaparse is write a converter from
it's vector-based parse trees into a nested hashmap AST.

On Tue, Aug 22, 2017 at 7:13 PM, Didier  wrote:

> Ya, I guess the article says that some DSL uses them, like hiccup, so
> maybe its only in the perspective of a DSL you'd need to parse, and not
> really for modeling business entities.
>
> Like this:
> (s/def ::temp (s/or :one string?
> :two int?))
>
> Will conform to a variant:
>
> => (s/conform ::temp "one-two")
> [:one "one-two"]
> => (s/conform ::temp 12)
> [:two 12]
>
> And not to a tagged record like:
> {:tag :one
>  :val "one-two"}
>
> But, I don't know, that seems like a different and uncommon use case, I
> don't really see this as using a sum type, just describing data to be
> parsed, which I guess the vector form can be easier to work with. I think
> the clojurescript AST is actually using tagged records, and most people
> find it too verbose because of it.
>
> Anyways, I'd still like to hear if there's a major benefit I'm overseeing,
> or a detail I'm not understanding, if any.
>
>
>
> P.S.: I figured the difference between (s/or) and (s/multi-spec) I think.
> S/or is like structural-types, my example actually doesn't work, because
> :filename and :url have the same structure, both string? So conform will
> not be able to tell them apart. So if you need to know any kind of semantic
> difference which the shape can not infer, (s/or) won't work, you'll need
> (s/multi-spec) instead, which are more like nominal-types. Multi-spec I
> guess can also use any function to select the appropriate spec, so they're
> more powerful, but often I think the way I'm using it will be most common.
>
>
> On Tuesday, 22 August 2017 18:00:21 UTC-7, tbc++ wrote:
>>
>> I think the article is a bit misleading. Variants were never that popular
>> in Clojure. Infact I've never seen them used in production code or the most
>> common Clojure libraries. So I'm a bit perplexed as to why the article
>> recommends them so strongly.
>>
>> So I think the answer is, they are a fun thought experiment in Clojure,
>> but are of limited usefulness due to the tools we have available that make
>> them unneeded.
>>
>> It's a bit like recommending that new users use actors in Clojure. Sure,
>> you can shoehorn them in, but there's a reason why they aren't the default.
>> --
>> “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.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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
I think the article is a bit misleading. Variants were never that popular
in Clojure. Infact I've never seen them used in production code or the most
common Clojure libraries. So I'm a bit perplexed as to why the article
recommends them so strongly.

So I think the answer is, they are a fun thought experiment in Clojure, but
are of limited usefulness due to the tools we have available that make them
unneeded.

It's a bit like recommending that new users use actors in Clojure. Sure,
you can shoehorn them in, but there's a reason why they aren't the default.
-- 
“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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
Great, so these approaches are suggesting we wrap every value in a vector
or a hash map (as the lisp cast article does). That doesn't really help
much at all. Why is:

[[:image/name "img.png"]
 [:encode/width 42]
 [:encode/height 33]]

Any better than

{:image/name "img.png"
 :encode/width 42
 :encode/height 33}

Or perhaps people aren't suggesting vectors of vectors, I don't know. All
of it makes no sense to me when I look at in-production Clojure code. I
don't pass image names around as bare strings. I pass them around as part
of a hashmap where the keys give context to the strings, and also allow me
to pass in other data about the parameter.

Variants and sum types seem to come from OCaml and the like where strict
typing makes them much more needed. But in Clojure we prefer heterogeneous
collections, so I just don't understand why I would ever want variants.
They complicate the code for really no benefit. The complexity they are
attempting to solve can be solved by simply using maps and records instead
of bare values.



On Tue, Aug 22, 2017 at 5:43 PM, James Reeves <ja...@booleanknot.com> wrote:

> On 22 August 2017 at 23:04, Timothy Baldridge <tbaldri...@gmail.com>
> wrote:
>
>> I find the arguments for variants very unconvincing. As you stated with
>> specs and s/keys you can spec the same sort of data, and in a way that's
>> much more open-ended.
>>
>> For example:
>>
>> [:person {:name "Tim" :grade "B"}]
>>
>> What is the type of this data? We would probably guess a :person. But
>> what if we wanted to "cast" it to a :student? Well then we'd have to change
>> the variant tag to :student, but then it would no longer be a person,
>> unless we introduced some sort of inheritance that said all students are
>> people.
>>
>
> I don't think that example is a representative use of variants in Clojure.
> More typically, variants are used like key/value pairings that exist
> outside a map. For example:
>
>   [:person/name "Tim"]
>
> If you actually have a map, the key/value pairs speak for themselves:
>
>   #:person{:name "Tim", :grade "B"}
>
> We can tell this is a "person" because it adheres to a particular shape,
> which can be specced out:
>
>   (s/def :person/student (s/keys :req [:person/name :person/grade]))
>
> But if you just have a key/value pairing, the value alone doesn't tell you
> much:
>
>   "Tim"
>
> Using a vector to represent a key/value seems to fit in well with how
> Clojure currently works:
>
>   (find m :person/name)
>   => [:person/name "Tim"]
>
> But there's no "s/variant" or "s/entry" spec that's as convenient to use
> as s/keys.
>
> --
> James Reeves
> booleanknot.com
>
> --
> 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.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: Sum types in Clojure? Better to represent as tagged records or as variant vectors?

2017-08-22 Thread Timothy Baldridge
I find the arguments for variants very unconvincing. As you stated with
specs and s/keys you can spec the same sort of data, and in a way that's
much more open-ended.

For example:

[:person {:name "Tim" :grade "B"}]

What is the type of this data? We would probably guess a :person. But what
if we wanted to "cast" it to a :student? Well then we'd have to change the
variant tag to :student, but then it would no longer be a person, unless we
introduced some sort of inheritance that said all students are people.

I much prefer spec:

(def ::person (s/keys :req [::name]))
(def ::student (s/keys :req [::grade ::name]))

I'm very much in the camp that longs for a super fast s/valid?
implementation so I could go and re-implement multi-methods and protocols
on top of spec. Much more flexible, and honestly it more correctly models
the real world.


On Tue, Aug 22, 2017 at 3:52 PM, Didier  wrote:

> I'm reading on http://www.lispcast.com/reduce-complexity-with-variants
> and have seen Jeanine's talk on her encoding scheme for sum types, but for
> some reason, I'm not convinced of the benefit over a tagged record
> encoding. I see that the positional vector or hash-map suggested in the
> lispcast article has a theoretically smaller number of states, but because
> it lacks names, it seems at a higher risk of human error. Anyone has
> thoughts on this? And now that we have specs, I feel like a multi-spec
> would address concerns of the tagged record encoding by being able to
> validate that the correct set of keys exist for the given type, while also
> having the benefit of named fields. What do others think?
>
> --
> 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.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: Is Clojure victim of Spec ?

2017-08-18 Thread Timothy Baldridge
Relevant discussion:
https://groups.google.com/d/msg/clojure/10dbF7w2IQo/ec37TzP5AQAJ

On Fri, Aug 18, 2017 at 10:53 AM, Rafik NACCACHE 
wrote:

> Hey guys,
>
> Seems to be a long while we are waiting for 1.9
>
> I kinda feel that core.spec seems to always need more polishing so that's
> why it's still being delayed... Am I right ?
>
> --
>
>
> [image: --]
>
> Rafik Naccache
> [image: https://]about.me/rafik_naccache
>
> 
>
> --
> 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.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: CHAMP an improvement on HAMT?

2017-08-14 Thread Timothy Baldridge
It came up today in the Clojurian's Slack mailing list, and it sounds like
the gist is that the papers did a bit of a apples-to-oranges comparison by
using a different hashing algorithm when comparing CHAMP to Clojure's
hashmaps. Once this difference is rectified the performance improvements
are much smaller, if they exist at all. Apparently CHAMP uses less memory,
and that might be a reason to switch, but I think the efforts to integrate
CHAMP mostly died when the fixed benchmarks failed to show significant
performance gains.

On Mon, Aug 14, 2017 at 3:00 AM, Didier  wrote:

> I think that paper is from 2015. Curious to hear what are people's
> thoughts as to why it didn't replace Clojure's HAMT. I wouldn't mind a free
> 3x performance boost and a reduced memory footprint. Is it just a matter of
> didn't have someone doing the work, or did it turn out that there was
> issues with CHAMP that would prevent Clojure's default core data structures
> from being migrated to it?
>
> --
> 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.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: How is this code to create a stateful lazy sequence?

2017-07-22 Thread Timothy Baldridge
If we think about what we're doing here is a stateful filter, then maybe we
could leverage a few more core Clojure functions:


(defn distinct-by [f coll]
  (let [seen (atom #{})]
(filter (fn [itm]
   (let [m (f itm)]
  (when-not (@seen m)
(swap! seen conj m
 coll)))

Now it's true, we're using a atom and a bit of mutability where none
existed before, but personally I think the intent is a bit clearer in this
code. What we're saying is "filter out all results we've seen before". If
this was production code I would probably replace the atom with a
`volatile!` but that's just for (small) performance reasons.


On Sat, Jul 22, 2017 at 7:36 AM, Rob Nikander 
wrote:

> Hi,
>
> Here's a function and a simple use of it. It works, but the code may not
> be good Clojure. I'm wondering how it might be better.
>
> (defn distinct-by
>   "Returns a sequence with no repeats of (f item).
>   A set is built up internally as the sequence is consumed, so don't use
> it on
>   an infinite sequence or you will run out of memory."
>   ([f coll]
> (letfn [(get-more [seen input-seq]
>(if (not (empty? input-seq))
>  (let [x (first input-seq)
>fx (f x)]
>(if (contains? seen fx)
>  (lazy-seq (get-more seen (rest input-seq)))
>  (lazy-seq (cons x (get-more (conj seen fx) (rest
> input-seq]
>(get-more #{} (seq coll)
>
> (def xs (list {:n 1, :a 'a} {:n 2, :a 'b} {:n 3, :a 'a} {:n 4, :a 'c} {:n
> 5, :a 'b}))
>
> (distinct-by :a xs)
> => ({:n 1, :a a} {:n 2, :a b} {:n 4, :a c})
>
> Rob
>
> --
> 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.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: Should the completion arity of a stateful transducer reset state?

2017-07-22 Thread Timothy Baldridge
Once a transducer is completed it should never be called again. This is why
transduce takes both a transducer and a reducing function and combines them
internally. The thought here is that it will be harder to shoot yourself in
the foot by reusing a stateful reducing function if you don't have to
combine the xf with the rf manually.

Timothy

On Sat, Jul 22, 2017 at 9:33 AM, David Bürgin  wrote:

> Hello all,
>
> I found an edge case where stateful transducers in core differ in
> whether they reset or clear state in the completion arity
> (partition-all) or don’t (take).
>
> Given the two transformed reducing functions
>
> (def conj-partitioning-all-3 ((partition-all 3) conj))
> (def conj-taking-3 ((take 3) conj))
>
> when performing transduction with those reducing functions twice in a
> row, one yields the same result twice, the other doesn’t.
>
> (transduce identity conj-partitioning-all-3 [] (range 10))
> ;; => [[0 1 2] [3 4 5] [6 7 8] [9]]
> ;; => [[0 1 2] [3 4 5] [6 7 8] [9]]
>
> (transduce identity conj-taking-3 [] (range 10))
> ;; => [0 1 2]
> ;; => []
>
> Question: which behaviour is the one I should emulate in my own
> transducers?
>
> Thank you,
> David
>
> --
> 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.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: How to eval one "step" of a form?

2017-07-20 Thread Timothy Baldridge
The answer lies in the term "REPL". You start by reading the string, you
can use `clojure.core/read-string` for this case. This will convert your
string into Clojure data:

"(+ 1 (* 2 2))" => (+ 1 (* 2 2))

That's the "R" part of "REPL", read.

Next step is "E" for "eval". We need to evaluate the structure. In a very
simple sort of way you can write eval thusly:

(defn simple-eval [form]
  (cond
(integer? form) form

(symbol? form)  (condp = form
 '+ +
 '* *)

(seq? form) (let [[f & args] (map simple-eval form)
 (apply f args

As you see this algorithm is recursive. And it's also a (very) simple lisp
interpreter. If we get an integer we return it. If we get a symbol we
return the matching function. If we get a seq, we recursively eval all the
contents of the seq then call the first resolved item passing it the args.
You could easily insert println expressions in the above code to see how it
step-by-step evals the code from left-to-right and from
deepest-to-shallowest expression.

This is known as an interpreter as it interprets the code more or less at
runtime. Now this sort of interpreter isn't exactly fast (although it's
very simple and easy to understand). So often language designers will
compile languages by preprocessing and transforming the input code into a
different language. C compiles to assembly. ClojureScript compiles to
JavaScript. And Clojure compiles to JVM byte code. The point of these
compilation steps is to remove the overhead of this interpreter.

The P in REPL stands for "Print". After we eval a form we print the result.

And then we "L"oop back to the start.

Hopefully this helps a bit.

Timothy


On Thu, Jul 20, 2017 at 4:39 PM, Lincoln Bergeson  wrote:

> Here's my how-to question for someone with in-depth knowledge of the
> clojure/clojurescript compiler:
>
> If I have a string representing a valid Clojure form, say for example, "(+
> 1 (* 2 (/ 6 3)))", how would I "reduce" this form to the form with one
> s-expr evaluated? That is, how would I obtain "(+ 1 (* 2 2))"? And then
> from there, how would I obtain "(+ 1 4)", and then "5"?
>
> I read through David Nolen's brief intro to the cljs compiler:
> https://github.com/swannodette/hello-cljsc  and suspect the answer lies
> in ASTs. I'm just not sure where to start.
>
> Forgive me if I should be posting this somewhere else, just not sure where
> else I can find an answer.
>
> --
> 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.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: Modern opengl bindings in clojure

2017-07-14 Thread Timothy Baldridge
Are the docs out of sync? Because the README talks about immutable APIs and
seq to array conversions, but the library itself is just a renaming wrapper
mapping stuff like GL/GLVertex to gl-vertex. I don't understand how that
makes the API "modern". Unless that part isn't written yet.

Timothy

On Fri, Jul 14, 2017 at 3:31 PM, Kevin Baldor 
wrote:

> I see that it's uploaded to clojars so it might be a bit late to ask, but
> what is the convention on naming libraries like this?
>
> I'm used to seeing something like clj-gl for libraries that provide a
> Clojure wrapper around an existing library.
>
> Regardless, this is awesome and I hope to play with it soon.
>
> On Fri, Jul 14, 2017 at 3:59 PM,  wrote:
>
>> This library is a work in progress, but is in a usable state and there is
>> unlikely to be any breaking changes to the api:
>>
>> https://github.com/bcbradle/gl
>>
>> --
>> 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.
>



-- 
“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.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: Been away a while

2017-07-14 Thread Timothy Baldridge
I recommend starting with this excellent talk, if you haven't already seen
it: https://www.youtube.com/watch?v=qDNPQo9UmJA

Aside from that I recommend taking a look at Pedestal. It's async and
streaming capabilities are some of the most advanced you can find in the
Clojure space, and its protocols-first design allows it to extended in many
ways. Also take a look at Vase, a data-described system for building
services with Clojure and Pedestal.
https://www.youtube.com/watch?v=_Cf-STRvFy8

On Fri, Jul 14, 2017 at 5:09 AM, Adrian Mowat 
wrote:

> Hi Everyone,
>
> I've been out of the Clojure scene for about 18 months due to an
> ill-advised detour into management.  Don't worry!  I've recovered pretty
> well but I was wondering if anyone can suggest what I should be looking at
> to bring me back up to speed.
>
> My current context is that I have a mediums sized rails monolith (~27,000
> LOC excluding tests) that I want to gradually break up into an event
> sourced/CQRS architecture.  I'm evaluating different approaches to writing
> my read and write services and I'm happy to rewrite some code. Spec looks
> like a very exciting way to define services.  Maybe there are some good
> libraries that might help.
>
> Thanks very much
>
> Adrian
>
> --
> 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.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: core.async vs continuations

2017-07-10 Thread Timothy Baldridge
Yes, calls to ! could be written with continuations, or call/cc,
but they are not implemented that way. Instead the code inside the body of
the `go` macro is rewritten into a statemachine. This sort of rewrite is a
lot like the rewrites that C# does for yield, and Cython does much of the
same sort of thing for Python generators.

This blog post goes into many of the details:
http://hueypetersen.com/posts/2013/08/02/the-state-machines-of-core-async/

But the gist is this:
1) Chop up the code into blocks normally via a variant of Single Static
Assignment compilation
2) Move all locals that need to exist across block transitions into a
array, or a object field
3) Store the current state ID in a field.
4) To "pause" the machine, store the id of the next block and exit the
function. Later on you can pick up again by grabbing the correct block id
from the object field and then jumping back into that block.

Timothy

On Mon, Jul 10, 2017 at 2:41 PM, Răzvan Rotaru 
wrote:

> Hi,
>
> Pardon the ignorance, I was just rewatching Rich Hickeys talk about
> core.async, and realized that the await call is actually a continuation
> (like call/cc from scheme). And if I am not mistaken, you can't implement
> call/cc with macros, so I suspect there is a difference, but I fail to see
> it. Hence, my message here.
>
> Thanks,
> Razvan
>
> --
> 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.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: core.async/close! locks on chans with pending transforms

2017-07-03 Thread Timothy Baldridge
A big reason they have to be run inside the lock is that they have to
operate in the context of the channel.

For example:

(chan (take 10))

Firstly we must recognize that transducer instances are *not* thread safe.
They should only ever be executed by one thread at a time. But channels
allow multiple puts and takes. Also channels are not processes, they are
simply rather complex lists with locks around them.

This means, if you want to execute take correctly you must ensure that only
one thread executes the take instance at one time, since channels already
operate via a channel-level lock, it makes sense to run the transducer
inside the channels' lock.

But that's also why it's always been recommended to stick with simple, non
cpu-intensive, non blocking operations in channel transducers.

Timothy

On Mon, Jul 3, 2017 at 4:30 PM, Kevin Downey  wrote:

> On 07/03/2017 03:12 PM, Vitalie Spinu wrote:
>
>>
>>
>>
>> On Monday, 3 July 2017 22:48:40 UTC+2, red...@gmail.com wrote:
>>
>>
>> Discussion of locks aside, doing blocking operations like io or >   >!! or basically anything that looks like it blocks and isn't >!
>> or > is a very bad idea in a transducer on a channel. You will (eventually)
>> block the threadpool and get deadlocks.
>>
>>
>>
>> Is this the limitation in general or only when I use the chan with
>> blocking transducer withing a go block?  Transducers are not run on a go
>> block, are they?
>>
>>
> It is kind of complicated, and I haven't traced through everything in
> channels.clj recently, but assume transducers are not magic, the
> computation has to occur on some real thread some where, and the best
> threads available to do that are the consumer thread and the producer
> thread. If those threads are both executing go blocks, and you have a
> transducer doing blocking stuff on a channel they operate on, you may not
> be technically "blocking" in the go block, but the channel machinery is now
> blocking before it yields control back to the go  block. Putting blocking
> operations in a transducer then operating on the channel from go blocks
> turns `!>` and ' blocks), in to operations that do block a whole OS thread, of which the
> core.async threadpool that go blocks execute on only has 8 by default.
>
> There is this sort of dance where control is handed back and forth between
> channels and go blocks without tying up a thread. When you introduce
> blocking in to the channel machinery (by making the channel execute a
> blocking operation as things are produced or consumed) then the dance stops
> and the thread waits.
>
> --
>> 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 > clojure+unsubscr...@googlegroups.com>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
> --
> And what is good, Phaedrus,
> And what is not good—
> Need we ask anyone to tell us these things?
>
> --
> 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.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 

Re: core.async/close! locks on chans with pending transforms

2017-07-03 Thread Timothy Baldridge
Transducers on channels lock the channel while they are running. This is by
design. So yes, the side-effect of this means that no other operation
(puts, takes or closes) can succeed while the transducer is running.

So the short answer is: If you have code that can take awhile to run, don't
put it in a channel transducer, put it in `async/pipeline(-blocking)`
instead.

On Mon, Jul 3, 2017 at 12:03 PM, Vitalie Spinu  wrote:

>
> Hi,
>
> Async/close! causes deadlocks if its reducer is stalled (e.g. waits for an
> event from
>  another chan).
>
> Consider:
>
>   (let [d (chan)
> s (chan 1 (map (fn [v]
>  (println "this:" v)
>  (println "from d:" (  v)))]
> (go (>! s 1))
> (Thread/sleep 100)
> (println "closing s")
> (async/close! s))
>
>   ;; =>
>   ;; this: 1
>   ;; closing s
>   ;; .. [lock]
>
> This is caused by (.lock mutex) in close! method here:
>
>https://github.com/clojure/core.async/blob/master/src/
> main/clojure/clojure/core/async/impl/channels.clj#L247
>
> I wonder if it is there "by design" or a bug. IMO it makes little sense to
> lock
> external code simply because chan's reducer function is stalled. Just as
> close!
> doesn't lock on pending puts it shouldn't stall on pending "half-puts".
>
> I need this for systems with inter-dependent chans. In the above example
> component 'd' is a dependency of 's', then system will halt in reverse
> order of
> dependencies closing `s` first.
>
> Thank you,
>
>Vitalie
>
> --
> 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.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: New guide: Reading Clojure Characters

2017-06-17 Thread Timothy Baldridge
Anonymous implies there might be some sort of auto gen going on (as there
is with anonymous functions), Irrelevant has my vote therefore. The other
characteristics are a side-effect of it being a naming convention (with no
official support by the compiler). Maybe that could be pointed out in
greater detail. So maybe an edit along the lines of:

"Note: _ does not have special functionality in the compiler, it is seen
the same as any other local or arg, therefore the same rules of uniqueness
and precedence apply with _ as they would with any other symbol"

Going into too much detail about what is allowed, and when ties the concept
to too many undocumented behaviors.

On Sat, Jun 17, 2017 at 12:51 PM, Gregg Reynolds  wrote:

>
>
> On Jun 17, 2017 1:27 PM, "Alex Miller"  wrote:
>
> A new guide is available on the Clojure site:
>
> https://clojure.org/guides/weird_characters
>
>
> suggestion: for '_' , Anonymous might be better than Irrelevant.  Also,
> maybe explicitly note that multiple _ are allowed.  ie it has 2
> characteristics: you cannot reference it in body, and you can have more
> than one.
>
> should i put suggestions to the list or jira or?
>
> -g
>
> --
> 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.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: [ANN] Chestnut 0.15.0

2017-05-29 Thread Timothy Baldridge
Might be good to provide a quick overview of what Chestnut is. It's been a
year, so I either missed the last announcement, or have forgotten in that
time. Also I see a link that would take me to the project page.

On Mon, May 29, 2017 at 5:03 AM, Arne Brasseur 
wrote:

> After almost a year I'm pleased to announce the next major version of
> Chestnut.
>
>
> Component
>
> The biggest change in this version is the use of Stuart Sierra's Component
> library, both on the frontend and on the backend, in combination with
> reloaded.repl and System.
>
> This makes this release a bit less minimalist than previous versions, but
> it's in line with Chestnut's goal to provide a solid default structure to
> build upon. It also allowed us to simplify some of the code around
> starting/stopping/reloading of the application, and should all in all
> provide a better REPL experience. It also makes it easier for Chestnut to
> support more features in the future in a way that is modular and
> maintainable.
>
>
> New features and changes
>
> Command line flags now start with a + (e.g. +http-kit) instead of --.
> This is more in line with what other templates are doing, and it works
> better with the way Leiningen deals with command line flags. The old flags
> are still supported as well.
>
> Three new UI frameworks are supported: +re-frame, +rum, and +om-next.
>
> A code_of_conduct.md is no longer included by default, instead it needs
> to be requested explicitly with +code-of-conduct. While we strongly
> encourage people to adopt a CoC, this is something that should be a
> deliberate choice, because it has implications on how a project is managed.
>
> (run) has been renamed to (go), to be more in line with reloaded.repl,
> and browser-repl has been renamed to (cljs-repl) to follow the Figwheel
> API. The old versions are still available as aliases, they will be removed
> in Chestnut 1.0.
>
> All dependencies have been upgraded to their latest versions, including
>
>- clojurescript 1.9.562
>- compojure 1.6.0
>- doo 0.1.7
>- environ 1.1.0
>- figwheel 0.5.10
>- http-kit 2.2.0
>- lein-cljsbuild 1.1.5
>- lein-environ 1.1.0
>- om 1.0.0-alpha48
>- org.clojure/tools.nrepl 0.2.13
>- reagent 0.6.0
>- ring 1.6.1
>- ring-defaults 0.3.0
>- transit-clj 0.8.300
>
> Popularity poll
>
> By default a lein new chestnut will "phone home", reporting the Chestnut
> version and command line flags being used. It is possible to opt-out with
> the +no-poll flag.
>
> No other information is stored, any logging for these requests is
> disabled. In particular there is no logging of the name given to the
> application, or of IP addresses or other identifiable information.
>
> The reason for collecting this information is to help us decide which
> features to focus on, and to get a sense of how many people are opting in
> to the snapshot releases for early feedback.
>
>
> Contributors
>
> Many thanks to the 41 people who have contributed to Chestnut since its
> inception in 2014. For this release I'd like to thank Jeff Wong in
> particular for pushing the Component integration forward.
>
> As the Clojure landscape keeps evolving, so must Chestnut evolve with it.
> Contributions big and small are highly appreciated, whether it's code,
> documentation, or testing. If you are interested in working on a feature
> then get in touch, I would be more than happy to provide mentoring and help
> you along the way. This applies to beginners and experienced developers
> equally.
>
> --
> 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.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this 

Re: slackpocalypse?

2017-05-18 Thread Timothy Baldridge
You know, there's this awesome bit of tech called IRC...someone should
check that out.

On Thu, May 18, 2017 at 3:31 PM, Gregg Reynolds  wrote:

> looks like access is restored, for me at least.  still, slack is making me
> a little nervous. and that's in addition to the 10K msg limit, which is a
> pain.  anybody know antything about ryver? https://ryver.com/
> ryver-vs-slack/
>
> On May 18, 2017 3:15 PM, "Gregg Reynolds"  wrote:
>
>> is it just me? i've been unable to connect to clojurians (by cellphone)
>> for about 30 minutes, but i can connect to other slack groups.
>>
>> have we hit https://github.com/clojurians/clojurians-chat/wiki/
>> Slackpocalypse?  we're almost to 10K subscribers.
>>
>> g
>>
>>
>> --
> 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.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: slackpocalypse?

2017-05-18 Thread Timothy Baldridge
It's not working for me. I'm in the US, connecting via Chrome.

On Thu, May 18, 2017 at 2:40 PM, Dragan Djuric  wrote:

> It works for me as always.
>
> On Thursday, May 18, 2017 at 10:34:33 PM UTC+2, Gregg Reynolds wrote:
>>
>>
>>
>> On May 18, 2017 3:32 PM, "Jason Stewart"  wrote:
>>
>> I'm experiencing the same thing, while I am able to connect with my other
>> slack teams.
>>
>>
>> this is not looking good.  https://davechen.net/2017/01/slack-user-limit/
>>
>>
>> On Thu, May 18, 2017 at 4:17 PM, Kenny Williams 
>> wrote:
>>
>>> I am not able to connect via the web UI or Slack app either.
>>>
>>>
>>> On Thursday, May 18, 2017 at 1:15:17 PM UTC-7, Gregg Reynolds wrote:

 is it just me? i've been unable to connect to clojurians (by cellphone)
 for about 30 minutes, but i can connect to other slack groups.

 have we hit https://github.com/clojurians/clojurians-chat/wiki/
 Slackpocalypse?  we're almost to 10K subscribers.

 g


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



-- 
“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.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: How to Create Clojure `defn` Functions automatically?

2017-05-13 Thread Timothy Baldridge
Okay, so I've read these SO articles about 4 times now, and I finally think
I'm starting to understand what the `intern` solution is doing. I would
recommend this then can we simply state that:

`(def x 42)`

is equal to

`(intern 'x 42)`

Except the first is a compiler special form (and hence requires a compiler
and/or macro system) while the other is a function (and requires a
namespace system). That will probably save people a ton of reading. Like I
said, I program Clojure a lot, and it took me about 60 minutes of reading
and thinking about this code before I finally figured out what the problem
and the solution and the solution being presented.


On Sat, May 13, 2017 at 4:49 PM, Alan Thompson <clooj...@gmail.com> wrote:

> I was just trying to answer a question posed by someone else, so I can't
> give details about the original motivation. I thought it was a good example
> of the capabilities of `intern` that I hadn't seen before, which could be
> useful in a dynamic case where one wanted to generate functions on the fly
> w/o using macros.
>
> A previous answer the OP was referred to
> <http://stackoverflow.com/questions/7852351/clojure-macro-to-generate-functions>
> was incomplete for the new question and I was trying to fill in the missing
> parts.
>
>
>
> On Sat, May 13, 2017 at 3:40 PM, Timothy Baldridge <tbaldri...@gmail.com>
> wrote:
>
>> Sorry, but this use of intern is a pointless. What does intern give you
>> that a let over a defn doesn't?
>>
>> On Sat, May 13, 2017 at 4:37 PM, Alan Thompson <clooj...@gmail.com>
>> wrote:
>>
>>> If anyone is interested, I cleaned up the question to (hopefully) make
>>> it clearer, as well as adding the macro-calling-a-macro solution.
>>>
>>> While some may consider it esoteric, I thought it was a good example of
>>> the power `intern` can provide, as well as a good way to avoid macros and
>>> stick to pure functions.
>>>
>>> Here is the re-worked version:  http://stackoverflow.com/ques
>>> tions/43958471/how-to-create-clojure-defn-functions-automati
>>> cally-without-macros/
>>>
>>> Alan
>>>
>>> On Thu, May 11, 2017 at 10:15 AM, Alan Thompson <clooj...@gmail.com>
>>> wrote:
>>>
>>>> Actually someone else wrote the original CLJS question (1):
>>>> http://stackoverflow.com/questions/43897632/mapped-calls-to
>>>> -clojurescript-macro
>>>>
>>>> It was marked as a duplicate of this question (2):
>>>> http://stackoverflow.com/questions/43897632/mapped-calls-to
>>>> -clojurescript-macroThis one also had an answer using `intern` to
>>>> avoid the need for a macro.
>>>>
>>>> I didn't think question (1) was an exact duplicate of (2), and I wanted
>>>> to work out the details of solving (1) using `intern` instead of macros (it
>>>> seemed like a good goal at the time...).  I tried to simplify question (1)
>>>> w/o the CLJS callback stuff, and may have oversimplified.
>>>>
>>>> Since question was closed as being a "duplicate" (in error, I think), I
>>>> couldn't answer there and posed the Q style answer separately at (3):
>>>> http://stackoverflow.com/questions/43904628/how-to-create-c
>>>> lojure-defn-functions-automatically
>>>>
>>>> The main goal I had here was simply finding a good way to avoid macros
>>>> when auto-generating functions, and to generalize/document the technique
>>>> described in (2) using `intern`.
>>>>
>>>> Alan
>>>>
>>>> P.S.  Regarding (3), Joel Spolsky, creator of StackOverflow, has often
>>>> encouraged people to post both a question and its answer on the site:
>>>> https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-ans
>>>> wer-your-own-questions  In fact, they even have a special button
>>>> for this purpose.
>>>>
>>>>
>>>>
>>>> On Thu, May 11, 2017 at 9:39 AM, Timothy Baldridge <
>>>> tbaldri...@gmail.com> wrote:
>>>>
>>>>> I assume this is a real problem you are encountering since you wrote
>>>>> the original Stack Overflow questions. As Dragan mentioned, this example
>>>>> doesn't warrant such a complex solution, maps and keywords *are* function,
>>>>> so all you really need is `foo` as a getter. Or even if they weren't
>>>>> functions you still have `(partial get foo)`.
>>>>>
>>>>> On Thu, May 11, 2017 at 10:27 AM, Alan Thompson 

Re: How to Create Clojure `defn` Functions automatically?

2017-05-13 Thread Timothy Baldridge
Sorry, but this use of intern is a pointless. What does intern give you
that a let over a defn doesn't?

On Sat, May 13, 2017 at 4:37 PM, Alan Thompson <clooj...@gmail.com> wrote:

> If anyone is interested, I cleaned up the question to (hopefully) make it
> clearer, as well as adding the macro-calling-a-macro solution.
>
> While some may consider it esoteric, I thought it was a good example of
> the power `intern` can provide, as well as a good way to avoid macros and
> stick to pure functions.
>
> Here is the re-worked version:  http://stackoverflow.com/
> questions/43958471/how-to-create-clojure-defn-functions-
> automatically-without-macros/
>
> Alan
>
> On Thu, May 11, 2017 at 10:15 AM, Alan Thompson <clooj...@gmail.com>
> wrote:
>
>> Actually someone else wrote the original CLJS question (1):
>> http://stackoverflow.com/questions/43897632/mapped-calls-
>> to-clojurescript-macro
>>
>> It was marked as a duplicate of this question (2):
>> http://stackoverflow.com/questions/43897632/mapped-calls-
>> to-clojurescript-macroThis one also had an answer using `intern` to
>> avoid the need for a macro.
>>
>> I didn't think question (1) was an exact duplicate of (2), and I wanted
>> to work out the details of solving (1) using `intern` instead of macros (it
>> seemed like a good goal at the time...).  I tried to simplify question (1)
>> w/o the CLJS callback stuff, and may have oversimplified.
>>
>> Since question was closed as being a "duplicate" (in error, I think), I
>> couldn't answer there and posed the Q style answer separately at (3):
>> http://stackoverflow.com/questions/43904628/how-to-create-
>> clojure-defn-functions-automatically
>>
>> The main goal I had here was simply finding a good way to avoid macros
>> when auto-generating functions, and to generalize/document the technique
>> described in (2) using `intern`.
>>
>> Alan
>>
>> P.S.  Regarding (3), Joel Spolsky, creator of StackOverflow, has often
>> encouraged people to post both a question and its answer on the site:
>> https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-ans
>> wer-your-own-questions  In fact, they even have a special button for
>> this purpose.
>>
>>
>>
>> On Thu, May 11, 2017 at 9:39 AM, Timothy Baldridge <tbaldri...@gmail.com>
>> wrote:
>>
>>> I assume this is a real problem you are encountering since you wrote the
>>> original Stack Overflow questions. As Dragan mentioned, this example
>>> doesn't warrant such a complex solution, maps and keywords *are* function,
>>> so all you really need is `foo` as a getter. Or even if they weren't
>>> functions you still have `(partial get foo)`.
>>>
>>> On Thu, May 11, 2017 at 10:27 AM, Alan Thompson <clooj...@gmail.com>
>>> wrote:
>>>
>>>> Since the original question was in CLJS, which has neither `intern` nor
>>>> `eval`, does that mean the macro mapping another macro approach is the only
>>>> solution there?
>>>>
>>>>
>>>> On Thu, May 11, 2017 at 9:18 AM, Alan Thompson <clooj...@gmail.com>
>>>> wrote:
>>>>
>>>>> I like the idea of using `eval` and  `memoize`.  I'll have to keep
>>>>> that in mind.
>>>>> Alan
>>>>>
>>>>> On Thu, May 11, 2017 at 7:58 AM, Timothy Baldridge <
>>>>> tbaldri...@gmail.com> wrote:
>>>>>
>>>>>> This is a somewhat weird answer to a overcomplicated problem. As
>>>>>> mentioned, the data is a map to start with, and maps are functions so
>>>>>> treating the maps as data is probably the best approach. And like Dragan,
>>>>>> I'm unsure why this example doesn't use `(data :able)`.
>>>>>>
>>>>>> When I do need to generate functions at runtime, and I can't use
>>>>>> macros (for the reasons mentioned), I'll either use a macro that creates 
>>>>>> a
>>>>>> var, or use eval perhaps in conjunction with a memoize. I used this a lot
>>>>>> in my work with JavaFx. Do some reflection, generate some code, eval the
>>>>>> code and return a function, memoize that process so we can get the
>>>>>> generated function via name. So the interface looks like this:
>>>>>>
>>>>>> ((get-setter button :text) "hey")
>>>>>>
>>>>>> Get-setter does a ton of reflection, but calling the returned
>&g

Re: class and case

2017-05-13 Thread Timothy Baldridge
Using a protocol is probably the optimal choice, since it also opens up the
dispatch allowing for extension without modifying exiting code. Downstream
users of your library can add extensions to your code without having to
create a patch.



On Sat, May 13, 2017 at 7:43 AM, Alex Miller  wrote:

> Or case on (.getName the-class).
>
> --
> 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.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: In search of the little transducer

2017-05-12 Thread Timothy Baldridge
Sure, you can contact me at the address used in this reply :)

Timothy Baldridge

On Fri, May 12, 2017 at 11:19 AM, Erlis Vidal <er...@erlisvidal.com> wrote:

> Is there a way I can contact Tim Baldridge for questions about the
> subscription?
>
> Thanks!
>
> On Sun, Jan 31, 2016 at 12:40 PM, Mars0i <marsh...@logical.net> wrote:
>
>> Thanks jjttjj, Magomimmo.  I do prefer reading to videos, but I'll
>> consider getting Baldridge's series anyway.  Seems worth it.  I don't mind
>> paying.
>>
>> --
>> 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.
>



-- 
“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.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: How to Create Clojure `defn` Functions automatically?

2017-05-11 Thread Timothy Baldridge
I assume this is a real problem you are encountering since you wrote the
original Stack Overflow questions. As Dragan mentioned, this example
doesn't warrant such a complex solution, maps and keywords *are* function,
so all you really need is `foo` as a getter. Or even if they weren't
functions you still have `(partial get foo)`.

On Thu, May 11, 2017 at 10:27 AM, Alan Thompson <clooj...@gmail.com> wrote:

> Since the original question was in CLJS, which has neither `intern` nor
> `eval`, does that mean the macro mapping another macro approach is the only
> solution there?
>
>
> On Thu, May 11, 2017 at 9:18 AM, Alan Thompson <clooj...@gmail.com> wrote:
>
>> I like the idea of using `eval` and  `memoize`.  I'll have to keep that
>> in mind.
>> Alan
>>
>> On Thu, May 11, 2017 at 7:58 AM, Timothy Baldridge <tbaldri...@gmail.com>
>> wrote:
>>
>>> This is a somewhat weird answer to a overcomplicated problem. As
>>> mentioned, the data is a map to start with, and maps are functions so
>>> treating the maps as data is probably the best approach. And like Dragan,
>>> I'm unsure why this example doesn't use `(data :able)`.
>>>
>>> When I do need to generate functions at runtime, and I can't use macros
>>> (for the reasons mentioned), I'll either use a macro that creates a var, or
>>> use eval perhaps in conjunction with a memoize. I used this a lot in my
>>> work with JavaFx. Do some reflection, generate some code, eval the code and
>>> return a function, memoize that process so we can get the generated
>>> function via name. So the interface looks like this:
>>>
>>> ((get-setter button :text) "hey")
>>>
>>> Get-setter does a ton of reflection, but calling the returned function
>>> remains fast due to the combination of eval and memoization.
>>>
>>>
>>>
>>> On Thu, May 11, 2017 at 2:55 AM, Dragan Djuric <draga...@gmail.com>
>>> wrote:
>>>
>>>> What's wrong with (foo :able) => "Adelicious!" and (:able foo) =>
>>>> "Adelicious!"?
>>>>
>>>>
>>>> On Thursday, May 11, 2017 at 9:20:19 AM UTC+2, Alan Thompson wrote:
>>>>>
>>>>> A recent question on StackOverflow raised the question of the best way
>>>>> to automatically generate functions. Suppose you want to automate the
>>>>> creation of code like this:
>>>>>
>>>>>
>>>>>
>>>>> (def foo
>>>>>   {:able"Adelicious!"
>>>>>:baker   "Barbrallicious!"
>>>>>:charlie "Charlizable"})
>>>>> (def bar
>>>>>   {:able"Apple"
>>>>>:baker   "Berry"
>>>>>:charlie "Kumquat"})
>>>>>
>>>>> (defn manual-my-foo [item] (get foo item))
>>>>> (defn manual-my-bar [item] (get bar item))
>>>>>
>>>>> (manual-my-foo :able) => "Adelicious!"
>>>>> (manual-my-bar :charlie) => "Kumquat"
>>>>>
>>>>>
>>>>> You could write a macro to generate one of these at a time, but you
>>>>> can't pass a macro to a higher-order function like `map`, so while this
>>>>> would work:
>>>>>
>>>>>
>>>>> (generate-fn :foo)  ;=> creates `my-foo` w/o hand-writing it
>>>>>
>>>>>
>>>>> this wouldn't work:
>>>>>
>>>>>
>>>>> (map generate-fn [:foo :bar :baz])
>>>>>
>>>>> While one could write a 2nd macro to replace `map`, this is a symptom
>>>>> of the "Turtles All the Way Down" problem. One workaround is to avoid
>>>>> macros altogether and use only functions to generate the required `my-foo`
>>>>> and `my-bar` functions.  The trick is to make use of the built-in Clojure
>>>>> function `intern`  both to save the newly generated functions into the
>>>>> global environment and to retrieve the pre-existing maps `foo` and `bar`.
>>>>> Full details are available Q at the StackOverflow post
>>>>> <http://stackoverflow.com/questions/43904628/how-to-create-clojure-defn-functions-automatically/43904717#43904717>
>>>>> .
>>>>>
>>>>> Enjoy,
>>>>> Alan
>>>>>
>>>>> --
>>>> You received this m

Re: How to Create Clojure `defn` Functions automatically?

2017-05-11 Thread Timothy Baldridge
This is a somewhat weird answer to a overcomplicated problem. As mentioned,
the data is a map to start with, and maps are functions so treating the
maps as data is probably the best approach. And like Dragan, I'm unsure why
this example doesn't use `(data :able)`.

When I do need to generate functions at runtime, and I can't use macros
(for the reasons mentioned), I'll either use a macro that creates a var, or
use eval perhaps in conjunction with a memoize. I used this a lot in my
work with JavaFx. Do some reflection, generate some code, eval the code and
return a function, memoize that process so we can get the generated
function via name. So the interface looks like this:

((get-setter button :text) "hey")

Get-setter does a ton of reflection, but calling the returned function
remains fast due to the combination of eval and memoization.



On Thu, May 11, 2017 at 2:55 AM, Dragan Djuric  wrote:

> What's wrong with (foo :able) => "Adelicious!" and (:able foo) =>
> "Adelicious!"?
>
>
> On Thursday, May 11, 2017 at 9:20:19 AM UTC+2, Alan Thompson wrote:
>>
>> A recent question on StackOverflow raised the question of the best way to
>> automatically generate functions. Suppose you want to automate the creation
>> of code like this:
>>
>>
>>
>> (def foo
>>   {:able"Adelicious!"
>>:baker   "Barbrallicious!"
>>:charlie "Charlizable"})
>> (def bar
>>   {:able"Apple"
>>:baker   "Berry"
>>:charlie "Kumquat"})
>>
>> (defn manual-my-foo [item] (get foo item))
>> (defn manual-my-bar [item] (get bar item))
>>
>> (manual-my-foo :able) => "Adelicious!"
>> (manual-my-bar :charlie) => "Kumquat"
>>
>>
>> You could write a macro to generate one of these at a time, but you can't
>> pass a macro to a higher-order function like `map`, so while this would
>> work:
>>
>>
>> (generate-fn :foo)  ;=> creates `my-foo` w/o hand-writing it
>>
>>
>> this wouldn't work:
>>
>>
>> (map generate-fn [:foo :bar :baz])
>>
>> While one could write a 2nd macro to replace `map`, this is a symptom of
>> the "Turtles All the Way Down" problem. One workaround is to avoid macros
>> altogether and use only functions to generate the required `my-foo` and
>> `my-bar` functions.  The trick is to make use of the built-in Clojure
>> function `intern`  both to save the newly generated functions into the
>> global environment and to retrieve the pre-existing maps `foo` and `bar`.
>> Full details are available Q at the StackOverflow post
>> 
>> .
>>
>> Enjoy,
>> Alan
>>
>> --
> 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.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: Faster diffing for large-ish nested data structures

2017-04-22 Thread Timothy Baldridge
Can Specter walk two sequences in lock-step? That's what's needed for a
good diffing engine, and that seems quite far removed from Specter's
design.

On Fri, Apr 21, 2017 at 11:22 PM, Mars0i  wrote:

> This might be a job for which Specter is particularly useful.  You might
> have to dive pretty deep into it, but if you get stuck, the creator Nathan
> Marz is often very helpful.
>
> --
> 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.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: Faster diffing for large-ish nested data structures

2017-04-19 Thread Timothy Baldridge
I've gotten really fast diffing in Clojure by using the following concepts:

1) If you can sometimes make parts of A and B be identical, then your
differ can skip checking those parts by doing a (identical? A B), this
improves performance
2) Take a side effecting approach, pass into the differ a function of (fn
[path a-val b-val] ...), and whenever you see a difference call that
function, this turns the differ into a event generator. From there it's
trivial to use transients, tuples, etc. to improve performance
3) If you can restrict yourself to maps, vectors and seqs, you can use
reduce-kv for maps and vectors, and walk the seq with a index count for the
latter. This will result in some rather efficient walking.

I used these methods in writing my data differ for Odin:
https://github.com/halgari/odin/blob/update-indicies/src/com/tbaldridge/odin/contexts/data.clj#L259-L384


Not perfect, but it's the fastest method I've come up with so far. Could
probably also replace the calls to condp with nested case statements.

Timothy

On Wed, Apr 19, 2017 at 5:32 PM, lvh <_...@lvh.io> wrote:

> Hi,
>
>
> I have two deeply nested data structures (consisting of maps, vecs and the
> occasional seq; althoguh I can make it maps and vecs consistently if need
> be). I want to compute (and store) diffs; ideally diffs that store [path
> oldval newval] so that I can apply them in either direction.
>
> Using clojure.data/diff on them takes a long time (well north of 10
> minutes on my new laptop).
>
> If I flatten these nested map out to entries they have about 2E5 entries.
> I'm expecting between 1E5 and 1E6 entries per map. These maps  represent
> the same data at two close points in time, so I'm expecting small
> differences. The tree is unbalanced: it has inconsistent depth and
> branching factors, but they're still going to be consistent between
> snapshots.
>
> Here are some ideas I'm trying (but I'm open to suggestions, experiences):
>
> - The machines I'm doing this on have plenty of beefy cores. Since the
> data structures are immutable, I should be able to parallelize this
> operation somewhat, even if it's only a constant speedup of ~4x or so. (I
> care about minor speedups since it takes 10 minutes, not 10 hours, to do
> the diff right now -- so it's entirely possible that enough small speedups
> add up.)
>
> - clojure.data/diff builds a giant data structure of things that are the
> same. I don't care about the parts that are the same; just parts that are
> different. That takes time.
>
> - clojure.data/diff doesn't use transients. While I'm not expecting a lot
> of diffs, this might be a speedup.
>
> I've found https://groups.google.com/forum/#!topic/clojure/VPpjlRC2INg ,
> but it appears that mostly doesn't go anywhere unless I want to maintain
> something that knows a lot about internal Clojure data structures :)
>
>
> lvh
>
> --
> 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.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: Derefs broken after clojure.tools.namespace.repl/refresh

2017-04-11 Thread Timothy Baldridge
Cursive has had a really good debugger for a long time. I don't use it
much, but when I need it it *just works*.

Timothy

On Tue, Apr 11, 2017 at 7:37 PM, Didier  wrote:

> A good debugger is indeed extremely useful for Clojure - I use one every
>> day :-)
>>
>
> Am I living in the past? I thought Clojure didn't have a way to step
> through code interactively?
>
> On Tuesday, 11 April 2017 16:30:14 UTC-7, Colin Fleming wrote:
>>
>> A good debugger is indeed extremely useful for Clojure - I use one every
>> day :-)
>>
>> On 12 April 2017 at 05:29, Didier  wrote:
>>
>>> Experimentation is good. This is indeed surprising. I think it shows
>>> that a good debugger would still sometime be useful in Clojure. I can't
>>> really explain what's happening.
>>>
>>> --
>>> 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.
>



-- 
“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.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: Derefs broken after clojure.tools.namespace.repl/refresh

2017-04-10 Thread Timothy Baldridge
You're reloading your namespaces from a non-repl thread, concurrently while
editing code in the repl. I don't think this is use case is supported by
tools.namespace.

On Mon, Apr 10, 2017 at 2:56 PM, Didier  wrote:

> Hum, not sure why you would do this, but I'm guessing refresh goes in an
> infinite async loop. You keep reloading a namespace which creates a thread
> to reload itself.
>
> I can't really explain why the symbol exists, but is not bound. I would
> have thought either the symbol would not exist, or the Var would contain
> the correct value.
>
> --
> 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.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 transducers in a new transducing context

2017-04-09 Thread Timothy Baldridge
In your example transducer, the problem is with the `result` parameter. The
specification of transducers is that the result of `(rf result x)` should
be fed into the next call to `rf`. In other words: (-> result (rf x1) (rf
x2) (rf x3))` trying to do that in a parallel context is next to
impossible. Not saying there isn't a way to code a transducer-like thing to
work with multiple threads, but the result of that would look a lot more
like core.async or Reactive Extensions, than the transducers we have today.

On Sun, Apr 9, 2017 at 4:57 PM, Alexander Gunnarson <
alexandergunnar...@gmail.com> wrote:

> That makes sense about them not being designed for that use case. I would
> add, though, that transducers could certainly be used in a parallel context
> *if* the current transducer implementations were abstracted such that you
> could pass internal state generator and modifier functions and use the
> correct ones in whichever context is appropriate (single-threaded
> read/write, sequentially multi-threaded read/write à la core.async,
> concurrently multi-threaded read/write à la core.reducers). In the case of
> `map-indexed`, the fact that its transducer uses a volatile as currently
> implemented is not part of the `map-indexed` "contract", if you will, and
> seems to me to be an implementation detail. One could just as easily write
> the transducer for `map-indexed` as below:
>
> (defn map-indexed-transducer-base [f box-mutable inc-mutable]
>   (fn [rf]
> (let [i (box-mutable -1)]
>   (fn
> ([] (rf))
> ([result] (rf result))
> ([result input]
>   (rf result (f (inc-mutable i) input)))
>
> (defn map-indexed-transducer-single-threaded [f]
>   (map-indexed-transducer-base f unsynchronized-mutable-long! 
> #(unsynchronized-mutable-swap!
> % inc))
>
> (defn map-indexed-transducer-sequentially-multi-threaded [f]
>   (map-indexed-transducer-base f volatile! #(vswap! % inc))
>
> (defn map-indexed-transducer-concurrently-multi-threaded [f]
>   (map-indexed-transducer-base f atom #(swap! % inc)) ; or an AtomicLong
> variant
>
>
> On Sunday, April 9, 2017 at 6:47:46 PM UTC-4, tbc++ wrote:
>>
>> Transducers were never designed to work in parallel context. So I'd
>> define any behavior that arises from using the same transducers in multiple
>> threads *at the same time*, as undefined behavior.
>>
>> On Sun, Apr 9, 2017 at 4:39 PM, Alexander Gunnarson <
>> alexander...@gmail.com> wrote:
>>
>>> I should add that, as Timothy pointed out, if multiple threads mutate
>>> and read the value but only one ever does so at a time, as is the case in
>>> `core.async`, then a volatile is sufficient. My preliminary conclusions
>>> above about volatiles apply only to concurrent mutation via e.g. `fold` or
>>> the like.
>>>
>>> Also, regarding the locks you mentioned, Seth, I read up a little on the
>>> Java memory model here
>>> 
>>> and I can confirm that a lock is sufficient to provide *both* write *and*
>>> read thread-safety guarantees:
>>>
>>> ... acquir[ing a] monitor ... has the effect of invalidating the local
 processor cache so that variables will be reloaded from main memory. We
 will then be able to see all of the writes made visible by the previous
 release.

>>>
>>> `Volatile` only provides a subset of these read-safety guarantees, so a
>>> `volatile` in addition to a lock is indeed overkill, if that's what is
>>> happening.
>>>
>>> On Sunday, April 9, 2017 at 6:19:51 PM UTC-4, Alexander Gunnarson wrote:

 It looks that way to me too, Seth, though I'd have to comb over the
 details of the locks implemented there to give a reasoned opinion of my
 own. But yes, if that's the case, the volatile isn't adding anything.

 Anyway, I'm not trying to poke holes in the current implementation of
 transducers — on the contrary, I'm very appreciative of and impressed by
 the efforts the clojure.core (and core.async) contributors have made on
 that and other fronts. Transducers are an extremely powerful and elegant
 way to express code that would otherwise be a lot more complex and
 difficult to reason about. I'm just trying to figure out where I can get
 away with having unsynchronized mutable versions of stateful transducers
 that currently use volatiles, and where I need even stronger measures of
 thread safety than volatiles.

 To take these thoughts further, I did a simple test to compare the
 three types of mutability we've been talking about (unsynchronized,
 volatile, and atomic — I can reproduce the code here if you'd like) and the
 takeaway is that `map-indexed` really does rely on atomic operations in a
 multithreaded context, as each index depends on the previous index value.
 When doing a `volatile`-based `map-indexed` in parallel on a small
 collection (8 elements), the `volatile` value stays 

Re: Using transducers in a new transducing context

2017-04-09 Thread Timothy Baldridge
Transducers were never designed to work in parallel context. So I'd define
any behavior that arises from using the same transducers in multiple
threads *at the same time*, as undefined behavior.

On Sun, Apr 9, 2017 at 4:39 PM, Alexander Gunnarson <
alexandergunnar...@gmail.com> wrote:

> I should add that, as Timothy pointed out, if multiple threads mutate and
> read the value but only one ever does so at a time, as is the case in
> `core.async`, then a volatile is sufficient. My preliminary conclusions
> above about volatiles apply only to concurrent mutation via e.g. `fold` or
> the like.
>
> Also, regarding the locks you mentioned, Seth, I read up a little on the
> Java memory model here
> 
> and I can confirm that a lock is sufficient to provide *both* write *and*
> read thread-safety guarantees:
>
> ... acquir[ing a] monitor ... has the effect of invalidating the local
>> processor cache so that variables will be reloaded from main memory. We
>> will then be able to see all of the writes made visible by the previous
>> release.
>>
>
> `Volatile` only provides a subset of these read-safety guarantees, so a
> `volatile` in addition to a lock is indeed overkill, if that's what is
> happening.
>
> On Sunday, April 9, 2017 at 6:19:51 PM UTC-4, Alexander Gunnarson wrote:
>>
>> It looks that way to me too, Seth, though I'd have to comb over the
>> details of the locks implemented there to give a reasoned opinion of my
>> own. But yes, if that's the case, the volatile isn't adding anything.
>>
>> Anyway, I'm not trying to poke holes in the current implementation of
>> transducers — on the contrary, I'm very appreciative of and impressed by
>> the efforts the clojure.core (and core.async) contributors have made on
>> that and other fronts. Transducers are an extremely powerful and elegant
>> way to express code that would otherwise be a lot more complex and
>> difficult to reason about. I'm just trying to figure out where I can get
>> away with having unsynchronized mutable versions of stateful transducers
>> that currently use volatiles, and where I need even stronger measures of
>> thread safety than volatiles.
>>
>> To take these thoughts further, I did a simple test to compare the three
>> types of mutability we've been talking about (unsynchronized, volatile, and
>> atomic — I can reproduce the code here if you'd like) and the takeaway is
>> that `map-indexed` really does rely on atomic operations in a multithreaded
>> context, as each index depends on the previous index value. When doing a
>> `volatile`-based `map-indexed` in parallel on a small collection (8
>> elements), the `volatile` value stays consistent — that is, all the correct
>> indices are passed to the mapping function. However, over a sufficiently
>> large collection (100 elements, though it could happen on smaller scales
>> too), the `volatile` value starts to break down: duplicate index values are
>> passed to the mapping function and the highest index value only ever
>> reaches 97 at the maximum. The same phenomenon happens, of course, with the
>> unsynchronized-mutable-box-based `map-indexed`, though it happens at a
>> small scale too (calling the unsynchronized `map-indexed` on 8 elements
>> operated on by 2 threads produces only 7 unique indices).
>>
>> My preliminary conclusions are:
>> - Unsynchronized mutability is fine in contexts known to be only
>> single-threaded, in which I could replace the `volatile` in `map-indexed`
>> and other transducers with unsynchronized mutable boxes.
>> - Volatiles are good when all you want to do is set the value and have
>> multiple threads always read the most up-to-date value, without having to
>> depend on a previous value via e.g. `inc`.
>> - Atomic boxes (`atom`, `AtomicLong`, etc.) are necessary when the
>> mutable value relies on the previous value via e.g. `inc`, as is the case
>> with `map-indexed`.
>>
>> My guess is that all this applies to e.g. the unsynchronized `ArrayList`
>> in `partition-by` as well, which might need to be a synchronized collection
>> or an immutable one boxed in an atom, but I haven't tested this.
>>
>> Would you agree with these conclusions, Seth and Timothy?
>>
>> On Sunday, April 9, 2017 at 1:56:38 PM UTC-4, Seth Verrinder wrote:
>>>
>>> I'll defer to Timothy on the particulars of core.async but it looks like
>>> [1] the transducer in channel is protected by a lock. If that's the case
>>> volatile isn't adding anything in terms memory barriers.
>>>
>>> 1: https://github.com/clojure/core.async/blob/master/src/mai
>>> n/clojure/clojure/core/async/impl/channels.clj#L71
>>>
>>> On Sunday, April 9, 2017 at 11:58:00 AM UTC-5, Alexander Gunnarson wrote:

 Thanks so much for your well-considered reply, Timothy! That makes
 sense about volatiles being used in e.g. core.async or core.reducers
 contexts where the reducing function that closes over the mutable value of
 the 

Re: Using transducers in a new transducing context

2017-04-09 Thread Timothy Baldridge
The volatile! is needed for the case where a transducer is only used by one
thread at a time, but the thread executing the transducer may change from
one call to the next. This happens fairly often with core.async. If you
used a non-atomic, non-volatile mutable field, the JVM would be free to
perform several optimizations (like keeping the local in a CPU register)
that would cause the value to not properly propagate to other threads in
the case of a context switch. Using volatile! tells the JVM to flush all
writes to this field by the time the next memory barrier rolls around. It
also tells the JVM to make sure it doesn't cache the reads to this field
across memory barriers.

It's a tricky subject, and one that's really hard to test, and frankly I
probably got some of the specifics wrong in that last paragraph, but that's
the general idea of why transducers use volatile!.

Timothy

On Sun, Apr 9, 2017 at 12:49 AM, Alexander Gunnarson <
alexandergunnar...@gmail.com> wrote:

> EDIT: Transducers are actually not safe in `fold` contexts as I thought:
>
> (let [f (fn [i x] (println (str "i " i " " (Thread/currentThread)))
> (flush) x)
>   r-map-indexed #(r/folder %2 (map-indexed %1))]
>   (->> [6 7 8 9 10]
>(r-map-indexed f)
>(r/fold 1 (fn ([] (vector)) ([x] x) ([a b] (into a b))) conj)))
>
> Produces:
>
> i 0 Thread[ForkJoinPool-1-worker-2,5,main]
> i 2 Thread[ForkJoinPool-1-worker-1,5,main]
> i 3 Thread[ForkJoinPool-1-worker-1,5,main]
> i 4 Thread[ForkJoinPool-1-worker-1,5,main]
> i 1 Thread[ForkJoinPool-1-worker-3,5,main]
>
> So you would have to be careful to e.g. create different `map-indexed`
> transducers for single-threaded (e.g. `unsynchronized-mutable` box) and
> multi-threaded (e.g. `atom` box) contexts.
>
> On Sunday, April 9, 2017 at 2:10:06 AM UTC-4, Alexander Gunnarson wrote:
>>
>> I was wondering the same thing, shintotomoe. This thread
>>  talks
>> about it as well. I think it's safe to assume that since `ArrayList` uses
>> unsynchronized mutability internally (a quick review of the GrepCode
>> entry for `ArrayList` confirms this
>> ),
>> then we can rest assured that a `volatile` box as opposed to a totally
>> unsynchronized mutable variable is unnecessary, even in the context of
>> `fold`. After all, `reduce` (and by extension, `transduce`) is only ever
>> going to be single-threaded unless the data structure in question
>> unexpectedly implements a multithreaded reduce, which should never happen
>> (and if it does, you likely have bigger problems). To be honest, I'm not
>> sure why `volatile` is used in transducers instead of e.g. an
>> `unsynchronized-mutable` box. There may be a good reason, but I'm not
>> seeing it immediately. I'd love to learn.
>>
>> On Thursday, January 1, 2015 at 10:36:13 PM UTC-5, shintotomoe wrote:
>>>
>>> Thank you for the superfast response. I take it implementing your own
>>> transducing process is not something you would usually do unless you have a
>>> unique use case (my own use case being already implemented by chan taking a
>>> transducer).
>>>
>>> Still, I was wondering about the use of ArrayList in partition-all, and
>>> the recommendation to use volatiles inside transducers, which seem at odds.
>>> It seems we don't need to implement transducers in a thread-safe way. Is
>>> that correct?
>>>
>>> On Friday, January 2, 2015 12:58:51 PM UTC+11, tbc++ wrote:

 Core.async already has pipeline, pipeline-blocking and pipeline-async.
 In addition you can use a transducer inside a channel. Use those instead.

 Timothy

 On Thu, Jan 1, 2015 at 6:55 PM, shintotomoe 
 wrote:

> I was wondering how to apply a transducer inside a go process. What
> I've so far is the following
>
> (defn pipe-xform [in-ch out-ch xform]
>   (let [tr
> (let [tr (xform (fn
>   ([result] result)
>   ([result input] (conj! result input]
>   (fn
> ([] (locking tr (persistent! (tr (transient [])
> ([input] (locking tr (persistent! (tr (transient []) input
> ))]
> (go-loop []
>   (if-some [value ( (do (doseq [v (tr value)]
>   (>! out-ch v))
> (recur))
> (do (doseq [v (tr)]
>   (>! out-ch v))
> (close! out-ch))
>
> Now, I could just do
>
> (let [xf-ch (chan 1 xform)]
>   (pipe in-ch xf-ch)
>   (pipe xf-ch out-ch)
>
>
> Or just redesign my code so that I can create in-ch or out-ch with the
> transducer directly, but I was wondering whether there are any obvious
> flaws with the pipe-xform implementation.
>
> In particular, I was wondering about the 

Re: was Re: ANN: Orchestra, complete instrumentation for clojure.spec

2017-04-06 Thread Timothy Baldridge
The power offered by spec is probably better compared against dependent
type systems like Idris. True static type systems run analysis at
compile-time, but spec allows you to perform very complex checks because
you have the power of full blown language.

For example, with spec you can write a function spec that says "Union is a
function that takes two hashsets. The return value of this function is a
hashset that contains all the values found in the hashset arguments".
That's impossible to statically check in most languages. Some languages
like Idris approach this level of expressibility, but when they fall short,
you're sunk. In spec you can always pop the escape hatch and write a custom
predicate in Clojure code.

So for me that's the tradeoff. I loose compile-time checking, but gain a
*ton* of power. And since types exist at run-time we can do cool things
like introspect them and generate data, documentation, better error
messages, or even run logic over them to write a static type checker.

On Thu, Apr 6, 2017 at 2:57 PM, Jeaye  wrote:

> On Thu, Apr 06, 2017 at 01:47:17PM -0700, Raoul Duke wrote:
> > I am writing to ignorantly sincerely ask how spec + Orchestra compares to
> > other statically typed out of the box JVM languages. What are the succint
> > wins over not Scala shudder but eg Kotlin Ceylon, heck Frege, et. al.?
>
> clojure.spec validates data at run-time. spec's instrumentation, and thus
> Orchestra's, checks function arguments, return values, etc _when the
> function is called_, not during AOT compilation.
>
> In contrast, a static type system would catch theses errors before the
> program itself even runs. In my opinion, clojure.spec + Orchestra still
> falls quite short of a static type system, but it's the best setup I've
> seen for automated data validation as it moves through all parts of your
> Clojure programs. Even in languages with static type systems (C++, even),
> you almost certainly won't get automatic validation of the data, for each
> function call, return, etc, given only a declarative spec. In that way,
> clojure.spec alone provides something of great value.
>
> Aside from that, you're talking about the gains of Clojure versus all of
> those languages you listed. That's not related to Orchestra and would
> likely be better answered by people more knowledgeable than me.
>
> --
> 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.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: go local variable binding

2017-03-16 Thread Timothy Baldridge
Yes, dynamic vars do not exist in CLJS, so naturally binding doesn't work
as you would expect.

On Thu, Mar 16, 2017 at 11:36 AM, Christian Weilbach <
whitesp...@polyc0l0r.net> wrote:

> You cannot do so in cljs though:
> http://dev.clojure.org/jira/browse/CLJS-1634
>
> Just in case you expect to write cross-platform code with dynamic bindings.
>
>
> Am 16.03.2017 um 01:01 schrieb Timothy Baldridge:
> > Yes, that should work fine, do your tests confirm otherwise? Also if
> > you're not doing a recur there's no reason to use `go-loop` you can just
> > use `go`.
> >
> > On Wed, Mar 15, 2017 at 4:44 PM, Eran Levi <levi...@gmail.com
> > <mailto:levi...@gmail.com>> wrote:
> >
> > Hi,
> > can I bind variables, same as I do for threads, for go routines, to
> > be local only for a particular go routine, and if I can't, how would
> > you mimic this behavior ?
> >
> > |
> > (defn print-stuff [s]
> >   (println s))
> >
> > (go-loop []
> >(binding [*out*(clojure.java.io/writer "foo.txt")]
> >   (print-stuff)))
> >
> > (go-loop []
> >(binding [*out*(clojure.java.io/writer "bar.txt")]
> >   (print-stuff)))
> > |
> >
> >
> > --
> > 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
> > <mailto: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
> > <mailto:clojure%2bunsubscr...@googlegroups.com>
> > For more options, visit this group at
> > http://groups.google.com/group/clojure?hl=en
> > <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
> > <mailto:clojure+unsubscr...@googlegroups.com>.
> > For more options, visit https://groups.google.com/d/optout
> > <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.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
> > <mailto: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.
>



-- 
“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.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: go local variable binding

2017-03-15 Thread Timothy Baldridge
Yes, that should work fine, do your tests confirm otherwise? Also if you're
not doing a recur there's no reason to use `go-loop` you can just use `go`.

On Wed, Mar 15, 2017 at 4:44 PM, Eran Levi  wrote:

> Hi,
> can I bind variables, same as I do for threads, for go routines, to be
> local only for a particular go routine, and if I can't, how would you mimic
> this behavior ?
>
> (defn print-stuff [s]
>   (println s))
>
> (go-loop []
>(binding [*out* (clojure.java.io/writer "foo.txt")]
>   (print-stuff)))
>
> (go-loop []
>(binding [*out* (clojure.java.io/writer "bar.txt")]
>   (print-stuff)))
>
>
> --
> 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.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: Contribute Specter to Clojure core?

2017-03-05 Thread Timothy Baldridge
>>  Specter is not a DSL.

Specter implements a set of terms (navigators) specific to the library that
are interpreted by the library (the transform function) to accomplish some
task for a specific domain (manipulating data structures). In the same way,
`update-in` is a DSL. Both Specter and `update-in` support certain
operators and have certain behaviors under difference occasions. Specter
may compile down to composed functions, or Clojure code, while `update-in`
is always interpreted, but the net effect is still the same. They both are
languages specific to a certain domain.

There's noting inherently wrong with using a DSL, they have their places.
The value of the DSL will different for each project and programmer. In
some cases the added cognitive overhead of learning the caveats of a new
DSL may be worth it when compared to the simplification the DSL offers.
Other times not so much, depends on the context.

Timothy

On Sun, Mar 5, 2017 at 7:14 AM, Nathan Marz  wrote:

> To answer a few comments/misconceptions on this thread:
>
> - Specter is not a DSL. Things like ALL and MAP-VALS are first class
> objects that implement the underlying navigator interface. Specter's core
> is a high-performance method of composing implementations of that
> interface. It makes zero assumptions about what kinds of data it will be
> used for. I think any DSL for this problem would ultimately either not be
> generic enough or would be overly complex.
> - If you want to use a number as a navigator, then extend the ImplicitNav
> protocol on numbers and return (nthpath this).
> - Zippers are an advanced form of navigation, and Specter integrates them
> fully in the com.rpl.specter.zipper namespace. However, zippers add
> significant overhead and indirection, and 99.9% of the time you don't need
> them (but they do have the occasional use).
> - I wrote at length about why I think Specter fills a major hole in
> Clojure: http://nathanmarz.com/blog/clojures-missing-piece.html
>
>
> On Saturday, March 4, 2017 at 9:55:49 PM UTC-5, Herwig Hochleitner wrote:
>>
>> 2017-03-05 0:25 GMT+01:00 Didier :
>> > I'm not too sure what the contribs are. Are they simply packages
>> maintained
>> > by the Clojure team itself, or are they actually part of the standard
>> > library?
>>
>> As I understand it, they aren't any more sanctioned than any
>> third-party library, but the goal is to provide a stock of clojure
>> libraries under the same license as clojure itself. Also they provide
>> a common CI and path into maven central.
>>
>> 2017-03-04 22:52 GMT+01:00 Gregg Reynolds :
>> > it's easy to imagine a more xsl-like (or even css-like) syntax with the
>> same
>> > functionality
>>
>> I don't know how it squares up against specter in terms of
>> performance, but I've always been fond of the selector-engine in
>> enlive, from an engineering elegance POV, as an interface for tree
>> query and update.
>> It utilizes zippers, but only ever does a single pass (save for some
>> weird selectors). Can specter substantially improve on zippers for
>> this workload?
>> Is there an underlying abstraction, that could sit next to clojure.zip
>> or clojure.data.zip?
>>
> --
> 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.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: [ANN] Odin 0.2.0 - Query DSL for Clojure

2017-02-24 Thread Timothy Baldridge
It's in the QA in the readme, but specter only queries a single path
through the data. Odin supports relations, joins, recursive rules, tabling,
etc.

Currently Specter will probably perform a bit better, but I hope to close
that gap in the future.


Timothy

On Fri, Feb 24, 2017 at 5:10 PM Didier <didi...@gmail.com> wrote:

> How does this compare to Specter?
>
>
> On Thursday, 23 February 2017 13:34:16 UTC-8, Alan Thompson wrote:
>
> Just came across this - it looks very cool!
> Alan
>
> On Sat, Dec 10, 2016 at 7:14 AM, Timothy Baldridge <tbald...@gmail.com>
> wrote:
>
> I just released the first official version of Odin (
> https://github.com/halgari/odin). Odin is a declarative, extensible query
> DSL for Clojure that leverages transducers to provide a high amount of
> generality while still maintaining acceptable performance.
>
> One of the biggest features of Odin is its ability to rapidly index and
> query "normal" Clojure data structures. Here is a quick example of this
> feature in practice:
>
> (let [orders [{:customer/name "Sam"
>:customer/id   3411}
>   {:customer/id 3411
>:order/items {1212 3}}
>   {:customer/id 3411
>:order/items {2232 2 4242 3}}
>   {:item/id1212
>:item/price 40.0}
>   {:item/id2232
>:item/price 100}
>   {:item/id4242
>:item/price 1.99}]]
>   (->> (o/for-query
>  (o/and
>(d/query orders ?customer :customer/name "Sam")
>(d/query orders ?customer :customer/id ?id)
>(d/query orders ?order :customer/id ?id)
>(d/query-in orders ?order [:order/items ?item-id] ?qty)
>(d/query orders ?item :item/id ?item-id)
>(d/query orders ?item :item/price ?price))
>  (* ?qty ?price))
>(reduce + 0)))
>
> ;; => 325.97
>
>
> In this example we are given a vector of maps, we are then finding a customer 
> by name,
>
> then walking a path through the data to find all the items that customer 
> ordered, the
>
> total price is then calculated via the normal multiply and sum.
>
>
> There are several other features supported by Odin, including transformation 
> of data
>
> (based on a query), tabling, Datomic support, and much more.
>
>
> I also did a video series on the development process of Odin if anyone is 
> interested:
> (https://www.youtube.com/watch?v=JyKySmcTR4g)
>
> --
> 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.
>
-- 
“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.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: Prgram uses a lot of swap

2017-02-24 Thread Timothy Baldridge
What are the JVM memory settings set at? And how much physical memory does
the box have?

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: Is this a bug that is already fixed?

2017-02-19 Thread Timothy Baldridge
That's a pretty old version of ClojureScript. Try upgrading to the latest.

Timothy

On Sun, Feb 19, 2017 at 2:17 PM, William la Forge 
wrote:

> I'll note that when I add a second entry to the map, everything is fine:
>>
>>
>  {:fix nil :local/contacts-capability contacts-capability}
>
> --
> 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.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: Contribute Specter to Clojure core?

2017-02-14 Thread Timothy Baldridge
While I've looked at Specter several times, I have yet to use it in a
project for many of the same reasons that Rangel mentioned. Either my data
is shallow enough that clojure.core functions work just fine, or my data is
complex enough that I need cross-entity joins, and arbitrary clojure logic.
In short: I don't often need a path-based transformer, I need a query
engine for Clojure data.

Timothy

On Tue, Feb 14, 2017 at 2:37 PM, Rangel Spasov  wrote:

> Nathan - Specter has been an indispensable part of any
> Clojure/ClojureScript that I've started in the recent 1+ years. From my
> experience with it so far (and I'm definitely not using it to its full
> potential) it has had one killer feature and that is modifying a nested 3+
> levels deep data structure that randomly contains vectors, maps, set, et
> al. For that use case it is a KILLER library - it's outright amazing (and I
> don't use that word lightly!). From that perspective, that would be two
> thumbs up for including it in Clojure proper (if it was up to me).
>
> Here comes the BUT :). The more I've used Specter, the more I've come to
> the opinion that the less you need Specter, the simpler your data structure
> "architecture" (I generally dislike that word hence the quotes lol) tends
> to be. In a bad case scenario, Specter might encourage someone to come up
> with a very deeply nested data structure when a much shallower would do the
> job. Now, I definitely know and generally agree with "100 functions on 1
> data structure is better than 10 functions on 10 data structures"
> recommendation. But from my 4+ years experience with Clojure, over-nesting
> your data structures tends to become a little bit like OOP inheritance
> where you overspecialize the data and the details about your data.
> Especially in the domain of UI programming/React/ReactNative but also for
> general backend data-processing and transformation I've found it easier AND
> simpler to rely more on data "composition" rather than data "inheritance".
> In other words, keeping your data structures generally shallow, 2 or
> maximum 3 levels deep.
>
> All that being said, there's many, many cases where the data you're
> presented with is set in stone either by the problem domain or another
> person before you (or your past self :) ). In those cases, Specter is
> ESSENTIAL. Places where I use it to great effect are random/unknown data
> structure processing for scraping/parsing HTML and processing various API
> responses where the data shape and structure is not under your control.
>
> Thank you once again for developing this great library - I'm looking
> forward to everyone's responses in this thread!
>
>
> On Tuesday, February 14, 2017 at 1:02:55 PM UTC-8, Nathan Marz wrote:
>>
>> One of the most common questions I get about Specter is whether it will
>> ever become part of Clojure core. I think it's an interesting proposal and
>> would like to see what the community and core team thinks.
>>
>> The primary reason for contributing would be that Specter makes Clojure a
>> stronger language. For a language that embraces simplicity, I've always
>> viewed the complexity of dealing with nested data structures a glaring
>> weakness of Clojure. The existing stuff in Clojure, like clojure.walk,
>> zippers, update-in, etc., just doesn't cut it. This problem is very common,
>> and Specter completely solves it with near-optimal performance.
>>
>> The main thing that makes me hesitate to suggest this is getting
>> bottlenecked on Clojure's dev process. However, Specter is very well
>> developed at this point so it doesn't need to move fast anymore.
>>
>> Please share your thoughts.
>>
> --
> 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.google.com/group/clojure?hl=en
--- 

Re: Clojure.spec, maps, restrict valid keywords, easier way?

2017-02-02 Thread Timothy Baldridge
A good editor should auto-complete your keywords for you. Since using this
feature in Cursive (same sort of thing is available in other editors) the
cases where I've mis-spelled a keyword have dropped dramatically. It's a
lot harder to mis-spell a keyword when you can just do: :egg/th and
the rest is auto-filled.

On Thu, Feb 2, 2017 at 5:37 PM, Alex Miller  wrote:

> Ugh, don't do that. Introducing layers that add no value is a bad idea.
> Just use the keyword directly.
>
> --
> 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.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.


  1   2   3   4   5   6   7   8   9   >