Re: avoiding casts with aget & friends

2019-01-30 Thread Alex Miller
On Wed, Jan 30, 2019 at 11:07 PM Brian Craft  wrote:

> With much experimentation, I ended up with this:
>
>   (let [a 1
> b (.longValue ^Long (:foo {:foo 3}))
> c (if (< a b) a b)])
>
> which seems to avoid the longCast call:
>
> Object o;
> if (_thunk__0__ == (o = _thunk__0__.get(const__3))) {
> o = (__thunk__0__ = __site__0__.fault(const__3)).get(const__3);
> }
> final long b = (long)o;
> final long c = (a < b) ? a : b;
>
> I don't know if this is advisable. Does anyone do this?
>

No, I wouldn't do this. `long` can inline so it's going to be better (it's
also more likely to jit well as it's used other places and is likely hotter
in the jit).

Going back to the original...

  (let [a 1
b (:foo {:foo 3})
c (if (< a b) a b)])

let will track primitives if possible.
- a is going to be a primitive long.
- (:foo {:foo 3}) is going to (always) return an Object and it's best to
recognize that and make an explicit cast to a primitive long.
- if a and b are both primitives, then < is able to inline a long-primitive
comparison (via Numbers.lt())
- the if is going to return an Object though, so again you'll probably want
to type hint or cast c, but it's hard to know for sure without seeing more
code

Without other info, I would probably start with

  (let [a 1
b (long (:foo {:foo 3}))
c (if (< a b) a b)])

Or alternately, it might be better to just type hint b in the comparison to
avoid reboxing b, but hard to know without more context:

  (let [a 1
b (:foo {:foo 3})
c (if (< a ^long b) a b)])

Comparing the bytecode for these (skipping everything up through the
keyword lookup, which is same for all):

Original:  Option 1:
 Option 2:
45: astore_2   45: invokestatic  #41   45:
astore_2
46: lload_0 48: lstore_2
 46: lload_0
47: aload_249: lload_0
47: aload_2
48: invokestatic  #41  50: lload_2  48:
checkcast #37
51: ifeq  62 51: lcmp
51: invokestatic  #43
54: lload_0 52: ifge  60
  54: lcmp
55: invokestatic  #45  55: lload_0  55:
ifge  66
58: goto  6556: goto  61
58: lload_0
61: pop   59: pop
 59: invokestatic  #49
62: aload_260: lload_2
62: goto  69
63: aconst_null   61: lstore4
 65: pop
64: astore_2   63: lload 4
 66: aload_2
65: astore_3   65: invokestatic  #47   67:
aconst_null
66: aload_3
68: astore_2
67: aconst_null
   69: astore_3
68: astore_3
   70: aload_3

   71: aconst_null

   72: astore_3

Option 1 does an lstore/lload (long) instead of an astore/lstore (object).
Both options use lcmp which is likely the fastest path to compare longs.
I've omitted some info here to make these fit, but Original line 48 will
invoke Numbers.lt:(JLjava/lang/Object;)Z which is the Numbers.lt(long,
Object) - lcmp is definitely going to be preferable to this. Also of
importance is that in Option 1, both a and b are stored as longs and loaded
as longs so if there is subsequent stuff to do on them, they can avoid
boxing (this is also betrayed by the shorter length from fewer casts).

Your longValue one is like Option 1, but starts:

  45: checkcast #37 // class java/lang/Long
  48: invokevirtual #41 // Method
java/lang/Long.longValue:()J

I guess I don't know whether that's faster than an invokestatic call to
clojure/lang/RT.longCast:(Ljava/lang/Object;)J, hard to tell without
testing in a real context. I'd certainly use the (long ...) one though
unless I proved it mattered.

-- 
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: avoiding casts with aget & friends

2019-01-30 Thread Brian Craft
With much experimentation, I ended up with this:

  (let [a 1
b (.longValue ^Long (:foo {:foo 3}))
c (if (< a b) a b)])

which seems to avoid the longCast call:

Object o;
if (_thunk__0__ == (o = _thunk__0__.get(const__3))) {
o = (__thunk__0__ = __site__0__.fault(const__3)).get(const__3);
}
final long b = (long)o;
final long c = (a < b) ? a : b;

I don't know if this is advisable. Does anyone do this?

Also just noted this is another case where explicitly calling something 
seems to make it disappear. :-p

On Wednesday, January 30, 2019 at 8:41:49 PM UTC-8, Brian Craft wrote:
>
> The full context is large. But, for example, in this code:
>
>   (let [a 1
> b (:foo {:foo 3})
> c (if (< a b) a b)])
>
> b and c are Object (if the disassembly is to be believed) which leads to 
> casts where c is used later. Also, the compare is calling Numbers.lt, which 
> is going to do a bunch of casting & dispatch.
>
> Adding a :long hint on b, b is still Object, and the compare becomes
>
> if (a < RT.longCast(b)) {
> num = Numbers.num(a);
> }
>
> with a long cast that doesn't seem necessary. Also, c is still Object.
>
> Casting the lookup to long, like (long (:foo {:foo 3})), b and c are now 
> long, but there's now a cast on the return of the lookup
>
> Object x;
> if (_thunk__0__ == (x = _thunk__0__.get(const__4))) {
> x = (__thunk__0__ = __site__0__.fault(const__4)).get(const__4);
> }
> final long b = RT.longCast(x);
> final long c = (a < b) ? a : b;
>
> which is going to hit the RT.longCast(Object) method, and start probing 
> for the class so it can pick a method.
>
>
> On Wednesday, January 30, 2019 at 6:58:07 PM UTC-8, Alex Miller wrote:
>>
>> It would really help to see a full function of code context. From that I 
>> could probably talk a little more about what I would expect the compiler to 
>> understand and how you might be able to influence it.
>>
>> On Wed, Jan 30, 2019 at 8:50 PM Brian Craft  wrote:
>>
>>> If there is unnecessary casting or boxing, how do you avoid it? hinting 
>>> and casting affect it, but not in ways I understand, or can predict.
>>>
>>> On Wednesday, January 30, 2019 at 6:06:37 PM UTC-8, Alex Miller wrote:

 Sometimes the insertion of profiling instrumentation magnifies the cost 
 of things in a hot loop or provides misleading hot spot info. If you're 
 using a tracing profiler, you might try sampling instead as it's less 
 prone 
 to this.

 Or, this sounds silly, but you can manually sample by just doing a few 
 thread dumps while it's running (either ctrl-\ or externally with kill -3) 
 and see what's at the top. If there really is a hot spot, this is a 
 surprisingly effective way to see it.

 For this kind of code, there is no substitute for actually reading the 
 bytecode and thinking carefully about where there is unnecessary casting 
 or 
 boxing.



 On Wed, Jan 30, 2019 at 6:55 PM Brian Craft  wrote:

> I haven't tried much. I'm getting the java 
> via clj-java-decompiler.core 'decompile' macro.
>
> A long cast does drop the cast (which is really counter-intuitive: 
> explicitly invoke 'long', which calls longCast, in order to avoid calling 
> longCast).
>
> Amusingly this doesn't reduce the total run-time, though longCast 
> drops out of the hotspot list. :-p There must be some other limiting step 
> that I'm missing in the profiler.
>
> I'm calling it around 1.2M times, so hopefully that engages the jit.
>
> On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>>
>> What have you tried? And how are you getting that Java? I would 
>> prefer to look at bytecode (via javap) to verify what you're saying. 
>>
>> Have you tried an explicit long cast?
>>
>> (aget flat-dict (bit-and 0xff (long (aget arr j
>>
>> Are you running this hot enough for the JIT to kick in? Usually this 
>> is the kind of thing it's good at, but it might take 10k invocations 
>> before 
>> it does.
>>
>>
>> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>>>
>>> Profiling is showing a lot of time spent in RT.longCast, in places 
>>> like this:
>>>
>>> (aget flat-dict (bit-and 0xff (aget arr j)))
>>>
>>> arr is hinted as ^bytes, and flat-dict as ^objects.
>>>
>>> which compiles to this:
>>>
>>> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
>>> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>>>
>>> Is there any way to avoid that RT.longCast? There is an aget method 
>>> in RT.java that returns a byte, and a longCast for byte, but I suspect 
>>> the 
>>> cast to Object is causing it to hit the longCast for 

Re: avoiding casts with aget & friends

2019-01-30 Thread Brian Craft
The full context is large. But, for example, in this code:

  (let [a 1
b (:foo {:foo 3})
c (if (< a b) a b)])

b and c are Object (if the disassembly is to be believed) which leads to 
casts where c is used later. Also, the compare is calling Numbers.lt, which 
is going to do a bunch of casting & dispatch.

Adding a :long hint on b, b is still Object, and the compare becomes

if (a < RT.longCast(b)) {
num = Numbers.num(a);
}

with a long cast that doesn't seem necessary. Also, c is still Object.

Casting the lookup to long, like (long (:foo {:foo 3})), b and c are now 
long, but there's now a cast on the return of the lookup

Object x;
if (_thunk__0__ == (x = _thunk__0__.get(const__4))) {
x = (__thunk__0__ = __site__0__.fault(const__4)).get(const__4);
}
final long b = RT.longCast(x);
final long c = (a < b) ? a : b;

which is going to hit the RT.longCast(Object) method, and start probing for 
the class so it can pick a method.


On Wednesday, January 30, 2019 at 6:58:07 PM UTC-8, Alex Miller wrote:
>
> It would really help to see a full function of code context. From that I 
> could probably talk a little more about what I would expect the compiler to 
> understand and how you might be able to influence it.
>
> On Wed, Jan 30, 2019 at 8:50 PM Brian Craft  > wrote:
>
>> If there is unnecessary casting or boxing, how do you avoid it? hinting 
>> and casting affect it, but not in ways I understand, or can predict.
>>
>> On Wednesday, January 30, 2019 at 6:06:37 PM UTC-8, Alex Miller wrote:
>>>
>>> Sometimes the insertion of profiling instrumentation magnifies the cost 
>>> of things in a hot loop or provides misleading hot spot info. If you're 
>>> using a tracing profiler, you might try sampling instead as it's less prone 
>>> to this.
>>>
>>> Or, this sounds silly, but you can manually sample by just doing a few 
>>> thread dumps while it's running (either ctrl-\ or externally with kill -3) 
>>> and see what's at the top. If there really is a hot spot, this is a 
>>> surprisingly effective way to see it.
>>>
>>> For this kind of code, there is no substitute for actually reading the 
>>> bytecode and thinking carefully about where there is unnecessary casting or 
>>> boxing.
>>>
>>>
>>>
>>> On Wed, Jan 30, 2019 at 6:55 PM Brian Craft  wrote:
>>>
 I haven't tried much. I'm getting the java via clj-java-decompiler.core 
 'decompile' macro.

 A long cast does drop the cast (which is really counter-intuitive: 
 explicitly invoke 'long', which calls longCast, in order to avoid calling 
 longCast).

 Amusingly this doesn't reduce the total run-time, though longCast drops 
 out of the hotspot list. :-p There must be some other limiting step that 
 I'm missing in the profiler.

 I'm calling it around 1.2M times, so hopefully that engages the jit.

 On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>
> What have you tried? And how are you getting that Java? I would prefer 
> to look at bytecode (via javap) to verify what you're saying. 
>
> Have you tried an explicit long cast?
>
> (aget flat-dict (bit-and 0xff (long (aget arr j
>
> Are you running this hot enough for the JIT to kick in? Usually this 
> is the kind of thing it's good at, but it might take 10k invocations 
> before 
> it does.
>
>
> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>>
>> Profiling is showing a lot of time spent in RT.longCast, in places 
>> like this:
>>
>> (aget flat-dict (bit-and 0xff (aget arr j)))
>>
>> arr is hinted as ^bytes, and flat-dict as ^objects.
>>
>> which compiles to this:
>>
>> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
>> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>>
>> Is there any way to avoid that RT.longCast? There is an aget method 
>> in RT.java that returns a byte, and a longCast for byte, but I suspect 
>> the 
>> cast to Object is causing it to hit the longCast for Object, which does 
>> a 
>> bunch of reflection.
>>
> -- 
 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 a topic in the 
 Google Groups "Clojure" group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/clojure/vXJFuOujTaw/unsubscribe.
 To unsubscribe from this group and 

Re: avoiding casts with aget & friends

2019-01-30 Thread Alex Miller
It would really help to see a full function of code context. From that I
could probably talk a little more about what I would expect the compiler to
understand and how you might be able to influence it.

On Wed, Jan 30, 2019 at 8:50 PM Brian Craft  wrote:

> If there is unnecessary casting or boxing, how do you avoid it? hinting
> and casting affect it, but not in ways I understand, or can predict.
>
> On Wednesday, January 30, 2019 at 6:06:37 PM UTC-8, Alex Miller wrote:
>>
>> Sometimes the insertion of profiling instrumentation magnifies the cost
>> of things in a hot loop or provides misleading hot spot info. If you're
>> using a tracing profiler, you might try sampling instead as it's less prone
>> to this.
>>
>> Or, this sounds silly, but you can manually sample by just doing a few
>> thread dumps while it's running (either ctrl-\ or externally with kill -3)
>> and see what's at the top. If there really is a hot spot, this is a
>> surprisingly effective way to see it.
>>
>> For this kind of code, there is no substitute for actually reading the
>> bytecode and thinking carefully about where there is unnecessary casting or
>> boxing.
>>
>>
>>
>> On Wed, Jan 30, 2019 at 6:55 PM Brian Craft  wrote:
>>
>>> I haven't tried much. I'm getting the java via clj-java-decompiler.core
>>> 'decompile' macro.
>>>
>>> A long cast does drop the cast (which is really counter-intuitive:
>>> explicitly invoke 'long', which calls longCast, in order to avoid calling
>>> longCast).
>>>
>>> Amusingly this doesn't reduce the total run-time, though longCast drops
>>> out of the hotspot list. :-p There must be some other limiting step that
>>> I'm missing in the profiler.
>>>
>>> I'm calling it around 1.2M times, so hopefully that engages the jit.
>>>
>>> On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:

 What have you tried? And how are you getting that Java? I would prefer
 to look at bytecode (via javap) to verify what you're saying.

 Have you tried an explicit long cast?

 (aget flat-dict (bit-and 0xff (long (aget arr j

 Are you running this hot enough for the JIT to kick in? Usually this is
 the kind of thing it's good at, but it might take 10k invocations before it
 does.


 On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>
> Profiling is showing a lot of time spent in RT.longCast, in places
> like this:
>
> (aget flat-dict (bit-and 0xff (aget arr j)))
>
> arr is hinted as ^bytes, and flat-dict as ^objects.
>
> which compiles to this:
>
> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL &
> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>
> Is there any way to avoid that RT.longCast? There is an aget method in
> RT.java that returns a byte, and a longCast for byte, but I suspect the
> cast to Object is causing it to hit the longCast for Object, which does a
> bunch of reflection.
>
 --
>>> 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 a topic in the
>>> Google Groups "Clojure" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/clojure/vXJFuOujTaw/unsubscribe.
>>> To unsubscribe from this group and all its topics, 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/vXJFuOujTaw/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

Re: avoiding casts with aget & friends

2019-01-30 Thread Brian Craft
If there is unnecessary casting or boxing, how do you avoid it? hinting and 
casting affect it, but not in ways I understand, or can predict.

On Wednesday, January 30, 2019 at 6:06:37 PM UTC-8, Alex Miller wrote:
>
> Sometimes the insertion of profiling instrumentation magnifies the cost of 
> things in a hot loop or provides misleading hot spot info. If you're using 
> a tracing profiler, you might try sampling instead as it's less prone to 
> this.
>
> Or, this sounds silly, but you can manually sample by just doing a few 
> thread dumps while it's running (either ctrl-\ or externally with kill -3) 
> and see what's at the top. If there really is a hot spot, this is a 
> surprisingly effective way to see it.
>
> For this kind of code, there is no substitute for actually reading the 
> bytecode and thinking carefully about where there is unnecessary casting or 
> boxing.
>
>
>
> On Wed, Jan 30, 2019 at 6:55 PM Brian Craft  > wrote:
>
>> I haven't tried much. I'm getting the java via clj-java-decompiler.core 
>> 'decompile' macro.
>>
>> A long cast does drop the cast (which is really counter-intuitive: 
>> explicitly invoke 'long', which calls longCast, in order to avoid calling 
>> longCast).
>>
>> Amusingly this doesn't reduce the total run-time, though longCast drops 
>> out of the hotspot list. :-p There must be some other limiting step that 
>> I'm missing in the profiler.
>>
>> I'm calling it around 1.2M times, so hopefully that engages the jit.
>>
>> On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>>>
>>> What have you tried? And how are you getting that Java? I would prefer 
>>> to look at bytecode (via javap) to verify what you're saying. 
>>>
>>> Have you tried an explicit long cast?
>>>
>>> (aget flat-dict (bit-and 0xff (long (aget arr j
>>>
>>> Are you running this hot enough for the JIT to kick in? Usually this is 
>>> the kind of thing it's good at, but it might take 10k invocations before it 
>>> does.
>>>
>>>
>>> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:

 Profiling is showing a lot of time spent in RT.longCast, in places like 
 this:

 (aget flat-dict (bit-and 0xff (aget arr j)))

 arr is hinted as ^bytes, and flat-dict as ^objects.

 which compiles to this:

 Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
 RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)

 Is there any way to avoid that RT.longCast? There is an aget method in 
 RT.java that returns a byte, and a longCast for byte, but I suspect the 
 cast to Object is causing it to hit the longCast for Object, which does a 
 bunch of reflection.

>>> -- 
>> 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 a topic in the 
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/clojure/vXJFuOujTaw/unsubscribe.
>> To unsubscribe from this group and all its topics, 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.


Re: avoiding casts with aget & friends

2019-01-30 Thread Chris Nuernberger
That is why I used 'unchecked-long' instead of 'long'.

(unchecked-long (unchecked-byte 5))

Not

(long (byte 5))


On Wed, Jan 30, 2019, 5:55 PM Brian Craft  I haven't tried much. I'm getting the java via clj-java-decompiler.core
> 'decompile' macro.
>
> A long cast does drop the cast (which is really counter-intuitive:
> explicitly invoke 'long', which calls longCast, in order to avoid calling
> longCast).
>
> Amusingly this doesn't reduce the total run-time, though longCast drops
> out of the hotspot list. :-p There must be some other limiting step that
> I'm missing in the profiler.
>
> I'm calling it around 1.2M times, so hopefully that engages the jit.
>
> On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>>
>> What have you tried? And how are you getting that Java? I would prefer to
>> look at bytecode (via javap) to verify what you're saying.
>>
>> Have you tried an explicit long cast?
>>
>> (aget flat-dict (bit-and 0xff (long (aget arr j
>>
>> Are you running this hot enough for the JIT to kick in? Usually this is
>> the kind of thing it's good at, but it might take 10k invocations before it
>> does.
>>
>>
>> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>>>
>>> Profiling is showing a lot of time spent in RT.longCast, in places like
>>> this:
>>>
>>> (aget flat-dict (bit-and 0xff (aget arr j)))
>>>
>>> arr is hinted as ^bytes, and flat-dict as ^objects.
>>>
>>> which compiles to this:
>>>
>>> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL &
>>> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>>>
>>> Is there any way to avoid that RT.longCast? There is an aget method in
>>> RT.java that returns a byte, and a longCast for byte, but I suspect the
>>> cast to Object is causing it to hit the longCast for Object, which does a
>>> bunch of reflection.
>>>
>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: avoiding casts with aget & friends

2019-01-30 Thread Alex Miller
Sometimes the insertion of profiling instrumentation magnifies the cost of
things in a hot loop or provides misleading hot spot info. If you're using
a tracing profiler, you might try sampling instead as it's less prone to
this.

Or, this sounds silly, but you can manually sample by just doing a few
thread dumps while it's running (either ctrl-\ or externally with kill -3)
and see what's at the top. If there really is a hot spot, this is a
surprisingly effective way to see it.

For this kind of code, there is no substitute for actually reading the
bytecode and thinking carefully about where there is unnecessary casting or
boxing.



On Wed, Jan 30, 2019 at 6:55 PM Brian Craft  wrote:

> I haven't tried much. I'm getting the java via clj-java-decompiler.core
> 'decompile' macro.
>
> A long cast does drop the cast (which is really counter-intuitive:
> explicitly invoke 'long', which calls longCast, in order to avoid calling
> longCast).
>
> Amusingly this doesn't reduce the total run-time, though longCast drops
> out of the hotspot list. :-p There must be some other limiting step that
> I'm missing in the profiler.
>
> I'm calling it around 1.2M times, so hopefully that engages the jit.
>
> On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>>
>> What have you tried? And how are you getting that Java? I would prefer to
>> look at bytecode (via javap) to verify what you're saying.
>>
>> Have you tried an explicit long cast?
>>
>> (aget flat-dict (bit-and 0xff (long (aget arr j
>>
>> Are you running this hot enough for the JIT to kick in? Usually this is
>> the kind of thing it's good at, but it might take 10k invocations before it
>> does.
>>
>>
>> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>>>
>>> Profiling is showing a lot of time spent in RT.longCast, in places like
>>> this:
>>>
>>> (aget flat-dict (bit-and 0xff (aget arr j)))
>>>
>>> arr is hinted as ^bytes, and flat-dict as ^objects.
>>>
>>> which compiles to this:
>>>
>>> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL &
>>> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>>>
>>> Is there any way to avoid that RT.longCast? There is an aget method in
>>> RT.java that returns a byte, and a longCast for byte, but I suspect the
>>> cast to Object is causing it to hit the longCast for Object, which does a
>>> bunch of reflection.
>>>
>> --
> 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/vXJFuOujTaw/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 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 of Clojure 2019 Survey!

2019-01-30 Thread Matching Socks
Clojure is to be commended for keeping the survey short. StackOverflow's 
(which is still open) is longer.  

-- 
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: avoiding casts with aget & friends

2019-01-30 Thread Brian Craft
I haven't tried much. I'm getting the java via clj-java-decompiler.core 
'decompile' macro.

A long cast does drop the cast (which is really counter-intuitive: 
explicitly invoke 'long', which calls longCast, in order to avoid calling 
longCast).

Amusingly this doesn't reduce the total run-time, though longCast drops out 
of the hotspot list. :-p There must be some other limiting step that I'm 
missing in the profiler.

I'm calling it around 1.2M times, so hopefully that engages the jit.

On Wednesday, January 30, 2019 at 3:39:41 PM UTC-8, Alex Miller wrote:
>
> What have you tried? And how are you getting that Java? I would prefer to 
> look at bytecode (via javap) to verify what you're saying. 
>
> Have you tried an explicit long cast?
>
> (aget flat-dict (bit-and 0xff (long (aget arr j
>
> Are you running this hot enough for the JIT to kick in? Usually this is 
> the kind of thing it's good at, but it might take 10k invocations before it 
> does.
>
>
> On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>>
>> Profiling is showing a lot of time spent in RT.longCast, in places like 
>> this:
>>
>> (aget flat-dict (bit-and 0xff (aget arr j)))
>>
>> arr is hinted as ^bytes, and flat-dict as ^objects.
>>
>> which compiles to this:
>>
>> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
>> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>>
>> Is there any way to avoid that RT.longCast? There is an aget method in 
>> RT.java that returns a byte, and a longCast for byte, but I suspect the 
>> cast to Object is causing it to hit the longCast for Object, which does a 
>> bunch of reflection.
>>
>

-- 
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: avoiding casts with aget & friends

2019-01-30 Thread Alex Miller
What have you tried? And how are you getting that Java? I would prefer to 
look at bytecode (via javap) to verify what you're saying. 

Have you tried an explicit long cast?

(aget flat-dict (bit-and 0xff (long (aget arr j

Are you running this hot enough for the JIT to kick in? Usually this is the 
kind of thing it's good at, but it might take 10k invocations before it 
does.


On Wednesday, January 30, 2019 at 4:03:43 PM UTC-6, Brian Craft wrote:
>
> Profiling is showing a lot of time spent in RT.longCast, in places like 
> this:
>
> (aget flat-dict (bit-and 0xff (aget arr j)))
>
> arr is hinted as ^bytes, and flat-dict as ^objects.
>
> which compiles to this:
>
> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>
> Is there any way to avoid that RT.longCast? There is an aget method in 
> RT.java that returns a byte, and a longCast for byte, but I suspect the 
> cast to Object is causing it to hit the longCast for Object, which does a 
> bunch of reflection.
>

-- 
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: avoiding casts with aget & friends

2019-01-30 Thread Chris Nuernberger
does doing an unchecked cast of the return value of the aget on the byte
array change things?

(defn test-fn
[]
(let [obj-ary (object-array 10)
  byte-data (byte-array (range 10))]
  (doseq [idx (range 10)]
(let [idx (int idx)]
  (aget obj-ary idx
(bit-and 0xFF (unchecked-long (aget byte-data
idx

This disassembled clearer and I think dropped the long cast.

On Wed, Jan 30, 2019 at 3:03 PM Brian Craft  wrote:

> Profiling is showing a lot of time spent in RT.longCast, in places like
> this:
>
> (aget flat-dict (bit-and 0xff (aget arr j)))
>
> arr is hinted as ^bytes, and flat-dict as ^objects.
>
> which compiles to this:
>
> Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL &
> RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)
>
> Is there any way to avoid that RT.longCast? There is an aget method in
> RT.java that returns a byte, and a longCast for byte, but I suspect the
> cast to Object is causing it to hit the longCast for Object, which does a
> bunch of reflection.
>
> --
> 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.


avoiding casts with aget & friends

2019-01-30 Thread Brian Craft
Profiling is showing a lot of time spent in RT.longCast, in places like 
this:

(aget flat-dict (bit-and 0xff (aget arr j)))

arr is hinted as ^bytes, and flat-dict as ^objects.

which compiles to this:

Object code2 = RT.aget((Object[])flat_dict, RT.intCast(0xFFL & 
RT.longCast((Object)RT.aget((byte[])arr2, RT.intCast(k)

Is there any way to avoid that RT.longCast? There is an aget method in 
RT.java that returns a byte, and a longCast for byte, but I suspect the 
cast to Object is causing it to hit the longCast for Object, which does a 
bunch of reflection.

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


[ANN] io.aviso/pretty 0.1.37

2019-01-30 Thread Howard Lewis Ship
https://github.com/AvisoNovate/pretty

> Sometimes, neatness counts

io.aviso/pretty is a library and Leiningen plugin that adds well formatted,
readable output of Clojure exceptions.
It's pretty indispensable to the tune of 1.9 million downloads, and is
integrated into the Ultra plugin as well as Boot.

This release is a cleanup, removing the totally unnecessary io.aviso.writer
namespace, and switching the Leiningen plugin from relying on implicit
middleware to
explicit middleware.

it was also a chance to verify that Pretty is still quite pretty with
Clojure 1.10.

-- 
Howard M. Lewis Ship

Senior Mobile Developer at Walmart Labs

(971) 678-5210
http://howardlewisship.com
@hlship

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


[ANN] Learn ClojureScript and re-frame - Video Course

2019-01-30 Thread jacek . schae
Hello,

I'm the guy who tries to push ClojureScript for more adoption in Web 
Development by creating high quality video courses.

My first course, very well recieved (https://www.learnreagent.com/#community), 
was released around 6 months ago.

Now I'm working on a new one and it's all about re-frame 

It covers these concepts:
   
   -   application state — app-db
   -   effects — db & fx
   -   subscriptions
   -   interceptors
   -   coeffects
   -   routing
   -   re-frame-http-fx
   -   re-frame-10x
   
The code has beed reviewd by these guys, to make sure it's best practice:

   - Daniel Compton - core contributor re-frame
   - Thomas Heller - creator shadow-cljs
   - Juho Teperi - core contributor reagent
   - Mike Thompson - creator re-frame

If you belive this could be something for your check it out -- 
https://www.learnreframe.com/

It's open for enrollment and the first videos will be available 24th of 
February

Thank you for reading this,
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.


Re: Inside Clojure Journal

2019-01-30 Thread Alex Miller
That's never actually worked. I keep meaning to remove it. :)

On Wednesday, January 30, 2019 at 1:41:16 PM UTC-6, puzzler wrote:
>
> +1.
>
> I can't seem to subscribe my email to Alex's blog using the form at the 
> bottom of the blog. Clicking the button does nothing. Anyone else having 
> that problem?
>
> On Tue, Jan 29, 2019 at 9:03 PM Shaun Parker  
> wrote:
>
>> I just wanted to say thanks to Alex for taking the time to journal all 
>> the Clojure things he's working on (and the non-Clojure things as well). 
>> They're enjoyable to read and eye-opening. It's a great window into the 
>> effort that he and others are putting into Clojure. It's been fun to follow 
>> the spec-alpha2 commits and get to read the thoughts/direction in the 
>> journal. Great work Alex!
>>
>> You can find them on the Inside Clojure blog: http://insideclojure.org/
>>
>> Shaun
>>
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

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


Re: Inside Clojure Journal

2019-01-30 Thread Mark Engelberg
+1.

I can't seem to subscribe my email to Alex's blog using the form at the
bottom of the blog. Clicking the button does nothing. Anyone else having
that problem?

On Tue, Jan 29, 2019 at 9:03 PM Shaun Parker  wrote:

> I just wanted to say thanks to Alex for taking the time to journal all the
> Clojure things he's working on (and the non-Clojure things as well).
> They're enjoyable to read and eye-opening. It's a great window into the
> effort that he and others are putting into Clojure. It's been fun to follow
> the spec-alpha2 commits and get to read the thoughts/direction in the
> journal. Great work Alex!
>
> You can find them on the Inside Clojure blog: http://insideclojure.org/
>
> Shaun
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: Invalid-token when dereferencing namespaced keywords.

2019-01-30 Thread Philip Markgraf
Thank you Justin, Andy, Alex and Thomas.
I now understand both the root of my issue (leading digits in keyword names 
is not allowed) and have a greater understanding of how keywords work, 
especially the reader's role in expanding double-colon keywords.




On Wednesday, January 30, 2019 at 2:53:15 AM UTC-8, Thomas Heller wrote:
>
> To expand on what Alex already mentioned. There is no such thing as 
> double-colon keywords. Double-colon is a reader alias mechanism that let 
> the reader resolve them so you can type less.
>
> (ns foo.bar.xyz)
>
> ::hello
>
> this is resolved at read-time and identical to actually writing
>
> :foo.bar.xyz/hello
>
> :: without a slash will use the current namespace as the namespace for 
> the keyword.
>
> If you have a require for another namespace and use :: with a slash you 
> can use it to resolve your require alias.
>
> (ns some.thing
>   (:require [foo.bar.xyz :as x]))
>
> ::x/hello
>
> again becomes
>
> :foo.bar.xyz/hello
>
> in your actual program. Nothing :: will ever exist at runtime.
>
> So if you want you can always use the fully qualified keyword directly or 
> you can let the require resolve them based on your ns require's. That means 
> you'll get an error if there is no alias to resolve
>
> (ns user2)
>
> ::user1/foo
>
> This is invalid because user2 does not have an alias to user1, instead it 
> is an actual full namespace.
>
> :user1/foo
>
> would be fine in this case (and identical to ::foo in user1). Or
>
> (ns user2
>   (:require [user1 :as u1]))
>
> ::u1/foo
>
> Hope that makes things clearer. 
>
> Cheers,
> Thomas
>

-- 
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: (gen/sample (s/gen #{'nil})): Couldn't satisfy such-that predicate

2019-01-30 Thread Alex Miller
On Wed, Jan 30, 2019 at 11:42 AM Rostislav Svoboda <
rostislav.svob...@gmail.com> wrote:

> Hi Alex,
>
> > You can see the special cases of nil, false, and true in the LispReader
> here if you're curious:
> >
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L393-L413
>
> I think it's not the special case of nil, false and true what's
> causing me headache. I'm having difficulties wrapping my head around
> following:
>
> ;; First quoting doesn't change the type:
> user=> (= (type 42) (type (quote 42)))
> true
>

(quote 42) is read as (quote 42). It then evaluates the list by invoking
quote. quote is a special form that returns the value you pass it, without
evaluation, so it evaluates to a long, whose type is java.lang.Long.


> ;; But consequent quoting changes the type. Ugh ???
> user=> (= (type 42) (type (quote (quote 42
> false
>

(quote (quote 42)) is going to be read by the Clojure reader just like
that: as the list (quote (quote 42)). The outer list is evaluated by
invoking quote, which is a special form that returns the value, without
evaluation. Here, that value is the list (quote 42) - that is, literally a
list containing the symbol quote and the long 42. If you check the type of
that you'll find it's a list (clojure.lang.IPersistentList).

user=> (quote (quote 42))
(quote 42)
user=> (type (quote (quote 42)))
clojure.lang.PersistentList


> My conclusion: a state has been introduced to the computation.
> (presumably by the quote)
> Or am I missing here something?
>

You seem to be missing the basic model for how Clojure reads and evaluates
source, so I would suggest reading up on that a bit more.

https://clojure.org/guides/learn/syntax#_evaluation
https://clojure.org/reference/reader
https://clojure.org/reference/evaluation
https://clojure.org/reference/special_forms



> Bost
>
> --
> 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/K74chBn4Pis/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 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: (gen/sample (s/gen #{'nil})): Couldn't satisfy such-that predicate

2019-01-30 Thread Rostislav Svoboda
Hi Alex,

> You can see the special cases of nil, false, and true in the LispReader here 
> if you're curious:
> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L393-L413

I think it's not the special case of nil, false and true what's
causing me headache. I'm having difficulties wrapping my head around
following:

;; First quoting doesn't change the type:
user=> (= (type 42) (type (quote 42)))
true
;; But consequent quoting changes the type. Ugh ???
user=> (= (type 42) (type (quote (quote 42
false

My conclusion: a state has been introduced to the computation.
(presumably by the quote)
Or am I missing here something?

Bost

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


Building out a Clojure Team?

2019-01-30 Thread Alex Mesropians
Hey All,

Are you looking to build out or hire clojure developers? 

If so check out Functional Works  to advertise your 
latest roles and target a pure FP market place : ) 

thanks!

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


Re: Invalid-token when dereferencing namespaced keywords.

2019-01-30 Thread Thomas Heller
To expand on what Alex already mentioned. There is no such thing as 
double-colon keywords. Double-colon is a reader alias mechanism that let 
the reader resolve them so you can type less.

(ns foo.bar.xyz)

::hello

this is resolved at read-time and identical to actually writing

:foo.bar.xyz/hello

:: without a slash will use the current namespace as the namespace for the 
keyword.

If you have a require for another namespace and use :: with a slash you can 
use it to resolve your require alias.

(ns some.thing
  (:require [foo.bar.xyz :as x]))

::x/hello

again becomes

:foo.bar.xyz/hello

in your actual program. Nothing :: will ever exist at runtime.

So if you want you can always use the fully qualified keyword directly or 
you can let the require resolve them based on your ns require's. That means 
you'll get an error if there is no alias to resolve

(ns user2)

::user1/foo

This is invalid because user2 does not have an alias to user1, instead it 
is an actual full namespace.

:user1/foo

would be fine in this case (and identical to ::foo in user1). Or

(ns user2
  (:require [user1 :as u1]))

::u1/foo

Hope that makes things clearer. 

Cheers,
Thomas

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