Comments inline...

I appreciate the discussion to date!

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Saturday, October 20, 2018 10:13 AM, Colin Fleming 
<colin.mailingl...@gmail.com> wrote:

>> I'm curious though, why additional macro / slightly differences from 
>> "idiomatic" seems so important to avoid.
>
> I can think of a couple of reasons off the top of my head:
>
> - It won't work with any tooling that's unaware of it, e.g. Cursive.

I agree -- my goal here isn't to add work everywhere.  I think most Cursive 
users probably would care less if it isn't added to Cursive, and if there was 
an actual demand, at least the code to implement would already be done in 
another library, and a trivial amount of code.

One nice thing about cider-nrepl/compliment is that multiple tools use them -- 
I like having this code complete from rebel-readline for example, and in theory 
(I say this because I haven't tested it), it should work in 
vim-fireplace/vim-replant/etc.

I like using it from a rebel-readline REPL over SSH for example -- completely 
outside of emacs/CIDER.

I think this "style" of tooling (not my syntax -- but tooling that is always 
integrated/present in the clojure process) yields this type of benefit -- I can 
use it from wherever I run my code if I'd like, actually independent of any 
editor or development environment.

> - It's very verbose - it's even worse than Java, because instead of 
> annotating each variable once where it's declared you have to annotate every 
> method call, and those annotations remain forever in the code, not just when 
> you're writing it. This is true even when the type is trivially obvious, e.g. 
> (String:charAt "my-string" 0).Modern languages are moving towards more 
> sophisticated type inference for a reason - it's much more comfortable.
>
> Really, this feature is just to make editors work better. Why not do 
> something similar to what Cursive does, and allow the user to type 
> (String:ch|) . Then just show the method completions from String and when the 
> user selects "charAt" just convert to (.charAt |)? This is really a feature 
> to aid code writing after all, not reading. Then the feature wouldn't require 
> macros at all, it could be a purely Emacs thing.

I agree -- if I knew more about emacs lisp I would have gone down this route 
initially.  However, my personal opinion is that this syntax does improve 
readability, at the price of additional verbosity -- a verbosity I personally 
don't mind while editing/writing because my editor helps me out.  The syntax 
itself is similar to C++/Java lambda method references...  Type:method.  I love 
immediately seeing what class a method is from when looking over code where I'm 
unfamiliar with the Java types being used.  But I agree -- this is subjective, 
and if I had more emacs lisp knowledge/time I would have thought much more 
about that route.  My main goal posting here was:
- Hey try this syntax out, it's helped me tremendously with Java interop in 
CIDER, and hopefully elicit some feedback (and I appreciate yours)
I hope it's obvious from the idea of pasting code into a repl to try the 
feature that this isn't *done/released/supported/warrantied/whatever*, but 
really is the beginnings of an idea being explored.  In fact, since I'm now 
starting to use this code more in one of my new interop-heavy projects, I've 
already made a couple of minor changes to it.  It took me much longer to find a 
minimal boot command that used tools/deps/cli and a paste-able code-snippet 
than writing it in the first place :-).

I don't see how this is related to type-inferencing at all.  Type-hinting the 
way we do in clojure is really a type declaration -- it isn't really trying to 
infer that say, something is a number based on usage (say, by being a 
participant in the '+' function --- on the contrary, if I want smart numerical 
"typing", I have to ^long or ^double).  Clojure simply casts/boxes to whatever 
the interop function expects.  If you're referring to the new Java syntax of 
'var x = new blah();' -- I think that's mainly a reaction to 
How<Many<<Templates<Can<we<Have<and>Still<Be<readAble>>>>>...
I'd almost argue what we do in Clojure is more like gradual typing -- I start 
to type for performance/interop reasons (numerical computing or Java interop) 
but only sparingly.  I don't doubt you are doing type inference in Cursive -- 
sounds like that's precisely how you are getting good completion lists.

> On Wed, 17 Oct 2018 at 11:13, 'somewhat-functional-programmer' via Clojure 
> <clojure@googlegroups.com> wrote:
>
>> I appreciate your detailed response, and you've certainly done great work 
>> with Cursive.  I always recommend it to any Java programmer who is starting 
>> to learn Clojure.  I will start to more seriously weigh the pros and 
>> consadditional of switching away from emacs.  The cult of emacs has had a 
>> strong pull on me but your good work may mean I should leave it for Clojure 
>> work too (and not just for Java work :-)).
>>
>> Cursive is doing much more in trying to match the Clojure compiler than I 
>> believe the compliment library has done to date.  Part of me likes the 
>> readability of the syntax:
>> (String:charAt my-string 0)
>> over
>> (-> ^String my-string (.charAt 0))
>> But I realize that is much more subjective than anything else.  I have to 
>> say, in delving into this even a little -- I appreciate the time you must 
>> have spent matching the Clojure compiler.  I just remember looking at Kawa's 
>> syntax for Java method calls and thinking, wow, I wish Clojure had that -- 
>> so much more readable!
>>
>> I like your last example a lot:
>> (foo .method) => getting turned into (.method foo) automatically by the 
>> editor.
>> I've actually looked at doing a similar thing with my macro -- basically 
>> using it in my editor, and then adding an nREPL middleware to transform it 
>> to the much beloved (.method obj args) notation.  Since I subjectively like 
>> the readability of (String:charAt obj 0) better than (.charAt ^String obj 0) 
>> I didn't go that route in this discussion.
>>
>> I'm curious though, why additional macro / slightly differences from 
>> "idiomatic" seems so important to avoid.  I think something as simple as 
>> (String:charAt obj 0) notation would be pretty simple for a third syntax 
>> (since we already have two built in ways of doing it) -- and closer to the 
>> static method invocation syntax -- so really a third built-in syntax 
>> (Integer/parseInt "12").  But that's more a philosophical question I suppose 
>> :-).  LISP curse anyone? :-)
>>
>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
>> On Wednesday, October 17, 2018 8:40 AM, Colin Fleming 
>> <colin.mailingl...@gmail.com> wrote:
>>
>>> Cursive already allows this with no syntax changes, but it does require 
>>> reproducing Clojure's type inference in the editor. Cursive performs this 
>>> type inference, so (modulo bugs) it knows the types of basically everything 
>>> that the Clojure compiler does (and in fact in some situations can do 
>>> better, but I deliberately use just what the compiler knows right now).
>>>
>>> This is used in various ways in completion. All of the cases that Aaron 
>>> enumerates above work, since Cursive can correctly propagate the types in 
>>> threading forms/doto etc (| is the caret):
>>>
>>> (-> "my-string"
>>>     (.ch|))    ; <- Only String methods here
>>>
>>> (-> (new MyType)
>>>     (.|))      ; <- MyType methods here
>>>
>>> (def foo "hello")
>>>
>>> (-> ^String foo
>>>     (.to|))    ; <- String completions here too, because of the type hint.
>>>                ;    Cursive can do better here even though the Clojure 
>>> compiler doesn't.
>>>                ;    Currently I restrict this, but completing could e.g. 
>>> automagically insert the type hint.
>>>
>>> (let [foo "string"]
>>>   (-> foo (.to|)) ; <- No type hint required, since we know the type of foo
>>>
>>> Additionally, Cursive supports the following:
>>>
>>> (let [foo (ArrayList.)
>>>       iterator (.iterator foo)]
>>>   (.ne|))      ; <- Here, .next will be offered even though Iterator isn't 
>>> imported,
>>>                ;    because Cursive knows the types we have in scope at the 
>>> caret.
>>>
>>> (let [foo (ArrayList.)]
>>>   (foo .i|))   ; <- Here, I've put the receiver first, then I'm completing 
>>> the method call.
>>>                ;    Since Cursive knows the type of foo, only ArrayList 
>>> methods will be completed.
>>>                ;    When I select a completion, Cursive will swap the two 
>>> around, like:
>>> (let [foo (ArrayList.)]
>>>   (.iterator foo|))
>>>
>>> I use this last one all the time, and it basically makes Clojure completion 
>>> as good as Java completion. Someone pointed out to me that this should 
>>> really use the existing dot syntax, like:
>>>
>>> (let [foo (ArrayList.)]
>>>   (. foo it|))  ; <- completes to:
>>>
>>> (let [foo (ArrayList.)]
>>>   (.iterator foo|))
>>>
>>> But I haven't implemented that yet.
>>>
>>> I don't do any of the more tricky stuff that IntelliJ does like 
>>> transitively searching across chained method calls based on the type, etc, 
>>> but that's just a time issue - there's nothing preventing Cursive from 
>>> doing that too. Also, offering completions from classes that are not 
>>> imported but are in scope makes a huge difference, even without any 
>>> switching trickiness.
>>>
>>> Cheers,
>>> Colin
>>>
>>> On Wed, 17 Oct 2018 at 04:34, Didier <didi...@gmail.com> wrote:
>>>
>>>> How does the new syntax help the tooling figure out the type?
>>>>
>>>> (def var (SomeType.))
>>>> (.method var)
>>>>
>>>> Or
>>>>
>>>> (jvm (var.method))
>>>>
>>>> I'm not sure how you narrow down to only the SomeType methods?
>>>>
>>>> --
>>>> 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](mailto:clojure%2bunsubscr...@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%2bunsubscr...@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](mailto:clojure%2bunsubscr...@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](mailto:clojure%2bunsubscr...@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.

Reply via email to