Re: Java like static typing for Clojure?

2016-10-21 Thread Daniel
> In this sort of situation, a static type system which provides universal 
> guarantees (this value can never be null) is more useful than a contract 
> system (no null values have been seen yet for the test inputs you've tried). 
> There's simply no way I can test all combinations, or reproduce all 
> combinations that users might have running.

Isn't a major selling point of generative testing to create loads of unique 
cases you can't invent on your own?

You don't trust it to do that? Is that from personal experience?  Genuinely 
curious because I am a little excited about using it in a project at work but 
this is disheartening.

-- 
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: Java like static typing for Clojure?

2016-10-21 Thread Daniel
> In this sort of situation, a static type system which provides universal 
> guarantees (this value can never be null) is more useful than a contract 
> system (no null values have been seen yet for the test inputs you've tried). 
> There's simply no way I can test all combinations, or reproduce all 
> combinations that users might have running.

Isn't a major selling point of generative testing was that it creates loads of 
unique cases you can't invent on your own?

You don't trust it to do that? Is that from personal experience?  Genuinely 
curious because I am a little excited about using it in a project at work but 
this is disheartening.

-- 
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: Java like static typing for Clojure?

2016-10-21 Thread Antonin Hildebrand
You could travel to the future and use ClojureScript with Kotlin as 
compilation target and a version of clojure.spec which resolves a subset of 
known constructs to Kotlin type annotations at compile-time :-p

Actually that idea of having a library of compile-time-recognizable spec 
constructs (like nil? string? or instance? predicates) is something I would 
like to see in ClojureScript today. It would generate type annotations for 
Closure Compiler to catch some class of simple bugs at compile time. But 
this is off-topic for this thread...

On Friday, October 21, 2016 at 7:41:31 PM UTC+2, Colin Fleming wrote:
>
> I tried it a couple of years ago, and my impressions were more or less the 
> same as CircleCI's here 
> . I found 
> the type annotation burden much higher than using a typed language such as 
> Kotlin, the type checking was very slow and the boundary between typed and 
> untyped code was really onerous. Ambrose has done some great work recently 
> though, so I should check it out again. However my general feeling is that 
> retrofitting something like Typed Clojure onto an existing language is 
> always going to be more difficult and fraught with problems than having a 
> language which was designed with the types in mind in the first place.
>
> Another possibility which I haven't had time to explore properly is Allen 
> Rohner's spectrum .
>
> Honestly, the easiest solution to my problem is probably just to use 
> Kotlin, which was designed by JetBrains for almost exactly my use case, has 
> great IDE support, and has a lot of smart people working full-time on it. 
> However that has a couple of problems: 1) it would make me sad and 2) I 
> would no longer be dogfooding Cursive all the time, which is a valuable 
> source of finding bugs during development. But at least I'd be spending all 
> my time on developing Cursive features, and not chasing NPEs or 
> investigating all this.
>
> On 21 October 2016 at 19:20, Josh Tilles  > wrote:
>
>> Out of curiosity, did you try Typed Clojure? It certainly has its rough 
>> edges, but you sound willing to bear the burden of annotating code with 
>> types (at the top-level, at least) and I *think* its treatment of Java 
>> interop does what you want: unless instructed otherwise, the typechecker 
>> assumes that arguments to Java methods must not be nil and that any Java 
>> method may return nil.
>>
>> On Thursday, October 20, 2016 at 8:39:04 AM UTC-4, Colin Fleming wrote:
>>>
>>> I recently spent a bunch of time researching exactly this. My motivation 
>>> was that my main project, Cursive, suffers from a ton of NPEs which I find 
>>> very difficult to manage. I wanted to see how difficult it would be to have 
>>> a typed Clojure-like thing, using something similar to Kotlin's type 
>>> system. Kotlin uses a type system which is similar to Java and has Java 
>>> interop as a primary goal, which I would also need since Java interop is 
>>> essential to me. It fixes a bunch of flaws in the Java type system and adds 
>>> new features like nullable types, which I now find it difficult to live 
>>> without.
>>>
>>> Before anyone asks, spec is not useful for me because it relies heavily 
>>> on generative testing to increase your confidence in your functions. I 
>>> can't use generative testing because my application is tied to a large Java 
>>> codebase which I cannot model to any useful degree. Essentially, spec 
>>> recommends runtime tests at the boundary of your system, and nearly my 
>>> entire system is interop boundary. I'm not interested in runtime checks 
>>> except where absolutely necessary - Kotlin does this for me transparently, 
>>> spec doesn't. 
>>>
>>> Here's a short list of my findings. I'm happy to expand on any of these 
>>> points if anyone is curious. It bears repeating - Java interop is 
>>> non-negotiable for me, and that makes a lot of this harder than it would be 
>>> otherwise.
>>>
>>> Disclaimer: I'm no programming language expert. This was hard for me, 
>>> and a surprising amount of it was new to me. I'd appreciate any corrections 
>>> or clarifications.
>>>
>>>1. Type systems are hard. I for one didn't appreciate the complexity 
>>>that goes into making them easy to use. Don't be fooled by the 20-line 
>>>implementations of Hindley-Milner.
>>>2. In particular, generics are very hard, and variance for generic 
>>>objects (i.e. the intersection of generic objects and OO) is the source 
>>> of 
>>>much difficulty.
>>>3. Type systems are split into two main camps - nominal typing (like 
>>>Java, where the types are identified by names) and structural typing, 
>>> where 
>>>the type of an object is defined by it's "shape", like Go's interfaces.
>>>4. One of the major benefits of Clojure is its heterogeneous 
>>>collections, a.k.a. "just use a map". This is very 

Re: Java like static typing for Clojure?

2016-10-21 Thread Colin Yates
Ironically I ran into an issue where I was receiving "" instead of nil
which caused some interesting behaviour.

For those who find these things interesting, this was for capturing
criteria in the UI which was sent to the server to filter. The
behaviour was:

 - form is nil, server ignores the query
 - enter some text, server sends the top N matching records
 - delete the text, you get the first top N records

I am sure you have guessed, but the cause was HTML input fields start
off as nil, enter something and then delete it and you get an empty
"". The server was checking (not (nil? criteria)) rather than (seq
criteria)there is a reason (seq ) is idiomatic :-).

On 21 October 2016 at 19:39, Sean Corfield  wrote:
> On 10/21/16, 10:40 AM, "Colin Fleming"  of colin.mailingl...@gmail.com> wrote:
>
>> Honestly, the easiest solution to my problem is probably just to use
>> Kotlin, which was
>
>> designed by JetBrains for almost exactly my use case, has great IDE
>> support, and has
>
>> a lot of smart people working full-time on it.
>
>
>
> And, to be fair, Kotlin has as a design goal to help address Java’s NPE
> issue. Whereas Clojure has, as part of its design, idiomatic nil-punning. If
> you’re doing a lot of Java interop, Kotlin is going to be a better fit.
>
>
>
> As for Typed Clojure, we’ve tried it a few times and the problems cited by
> CircleCI and by yourself are why we’ve given up on it each time. I will say,
> in Typed Clojure’s defense, that it gets better and better each time I try
> it so it’s definitely going in the right direction – but it is a very hard
> problem to solve!
>
>
>
> Pretty much the only time I ever see NPEs is when my Clojure code touches
> Java interop. And, yes, that can mean numeric ops (since those are
> implemented directly in Java) and string manipulation (again, implemented on
> top of Java).
>
>
>
> As an experiment, I tried a version of clojure.string where nil was always
> treated as “” and it does indeed avoid the NPEs but it comes at a
> performance cost (calling str or adding nil conditions). In the domain in
> which I work, nil -> “” is pretty much universally the right thing so it’s a
> cost we’re considering swallowing, for the extra simplicity it would bring
> to our code (i.e., creating a drop-in replacement of clojure.string that
> implements all of the functions with added str calls as needed – many can be
> handled mechanically).
>
>
>
> We don’t do much numeric work so we don’t hit NPEs in that Java interop
> boundary very often. There tho’ there is almost no argument that nil -> 0
> would be the “right thing” so suffering NPEs instead of some
> NonNumericArgumentException thing isn’t such a horrible trade off.
>
>
>
> 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
>
>
>
> On 10/21/16, 10:40 AM, "Colin Fleming"  of colin.mailingl...@gmail.com> wrote:
>
>
>
> I tried it a couple of years ago, and my impressions were more or less the
> same as CircleCI's here. I found the type annotation burden much higher than
> using a typed language such as Kotlin, the type checking was very slow and
> the boundary between typed and untyped code was really onerous. Ambrose has
> done some great work recently though, so I should check it out again.
> However my general feeling is that retrofitting something like Typed Clojure
> onto an existing language is always going to be more difficult and fraught
> with problems than having a language which was designed with the types in
> mind in the first place.
>
>
>
> Another possibility which I haven't had time to explore properly is Allen
> Rohner's spectrum.
>
>
>
> Honestly, the easiest solution to my problem is probably just to use Kotlin,
> which was designed by JetBrains for almost exactly my use case, has great
> IDE support, and has a lot of smart people working full-time on it. However
> that has a couple of problems: 1) it would make me sad and 2) I would no
> longer be dogfooding Cursive all the time, which is a valuable source of
> finding bugs during development. But at least I'd be spending all my time on
> developing Cursive features, and not chasing NPEs or investigating all this.
>
>
>
>
>
> --
> 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 

Re: Java like static typing for Clojure?

2016-10-21 Thread Sean Corfield
On 10/21/16, 10:40 AM, "Colin Fleming"  wrote:

> Honestly, the easiest solution to my problem is probably just to use Kotlin, 
> which was

> designed by JetBrains for almost exactly my use case, has great IDE support, 
> and has

> a lot of smart people working full-time on it.

 

And, to be fair, Kotlin has as a design goal to help address Java’s NPE issue. 
Whereas Clojure has, as part of its design, idiomatic nil-punning. If you’re 
doing a lot of Java interop, Kotlin is going to be a better fit.

 

As for Typed Clojure, we’ve tried it a few times and the problems cited by 
CircleCI and by yourself are why we’ve given up on it each time. I will say, in 
Typed Clojure’s defense, that it gets better and better each time I try it so 
it’s definitely going in the right direction – but it is a very hard problem to 
solve!

 

Pretty much the only time I ever see NPEs is when my Clojure code touches Java 
interop. And, yes, that can mean numeric ops (since those are implemented 
directly in Java) and string manipulation (again, implemented on top of Java).

 

As an experiment, I tried a version of clojure.string where nil was always 
treated as “” and it does indeed avoid the NPEs but it comes at a performance 
cost (calling str or adding nil conditions). In the domain in which I work, nil 
-> “” is pretty much universally the right thing so it’s a cost we’re 
considering swallowing, for the extra simplicity it would bring to our code 
(i.e., creating a drop-in replacement of clojure.string that implements all of 
the functions with added str calls as needed – many can be handled 
mechanically).

 

We don’t do much numeric work so we don’t hit NPEs in that Java interop 
boundary very often. There tho’ there is almost no argument that nil -> 0 would 
be the “right thing” so suffering NPEs instead of some 
NonNumericArgumentException thing isn’t such a horrible trade off.

 

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

 

On 10/21/16, 10:40 AM, "Colin Fleming"  wrote:

 

I tried it a couple of years ago, and my impressions were more or less the same 
as CircleCI's here. I found the type annotation burden much higher than using a 
typed language such as Kotlin, the type checking was very slow and the boundary 
between typed and untyped code was really onerous. Ambrose has done some great 
work recently though, so I should check it out again. However my general 
feeling is that retrofitting something like Typed Clojure onto an existing 
language is always going to be more difficult and fraught with problems than 
having a language which was designed with the types in mind in the first place.

 

Another possibility which I haven't had time to explore properly is Allen 
Rohner's spectrum.

 

Honestly, the easiest solution to my problem is probably just to use Kotlin, 
which was designed by JetBrains for almost exactly my use case, has great IDE 
support, and has a lot of smart people working full-time on it. However that 
has a couple of problems: 1) it would make me sad and 2) I would no longer be 
dogfooding Cursive all the time, which is a valuable source of finding bugs 
during development. But at least I'd be spending all my time on developing 
Cursive features, and not chasing NPEs or investigating all this.

 

 

-- 
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: Java like static typing for Clojure?

2016-10-21 Thread Colin Fleming
Absolutely, both that and the dogfooding are compelling arguments :-)

On 21 October 2016 at 20:04, Colin Yates  wrote:

> "making me sad" is unsustainable - problem solving with 1s and 0s is
> hard enough as it is without using demotivating tools :-).
>
> On 21 October 2016 at 18:40, Colin Fleming 
> wrote:
> > I tried it a couple of years ago, and my impressions were more or less
> the
> > same as CircleCI's here. I found the type annotation burden much higher
> than
> > using a typed language such as Kotlin, the type checking was very slow
> and
> > the boundary between typed and untyped code was really onerous. Ambrose
> has
> > done some great work recently though, so I should check it out again.
> > However my general feeling is that retrofitting something like Typed
> Clojure
> > onto an existing language is always going to be more difficult and
> fraught
> > with problems than having a language which was designed with the types in
> > mind in the first place.
> >
> > Another possibility which I haven't had time to explore properly is Allen
> > Rohner's spectrum.
> >
> > Honestly, the easiest solution to my problem is probably just to use
> Kotlin,
> > which was designed by JetBrains for almost exactly my use case, has great
> > IDE support, and has a lot of smart people working full-time on it.
> However
> > that has a couple of problems: 1) it would make me sad and 2) I would no
> > longer be dogfooding Cursive all the time, which is a valuable source of
> > finding bugs during development. But at least I'd be spending all my
> time on
> > developing Cursive features, and not chasing NPEs or investigating all
> this.
> >
> > On 21 October 2016 at 19:20, Josh Tilles 
> wrote:
> >>
> >> Out of curiosity, did you try Typed Clojure? It certainly has its rough
> >> edges, but you sound willing to bear the burden of annotating code with
> >> types (at the top-level, at least) and I think its treatment of Java
> interop
> >> does what you want: unless instructed otherwise, the typechecker assumes
> >> that arguments to Java methods must not be nil and that any Java method
> may
> >> return nil.
> >>
> >> On Thursday, October 20, 2016 at 8:39:04 AM UTC-4, Colin Fleming wrote:
> >>>
> >>> I recently spent a bunch of time researching exactly this. My
> motivation
> >>> was that my main project, Cursive, suffers from a ton of NPEs which I
> find
> >>> very difficult to manage. I wanted to see how difficult it would be to
> have
> >>> a typed Clojure-like thing, using something similar to Kotlin's type
> system.
> >>> Kotlin uses a type system which is similar to Java and has Java
> interop as a
> >>> primary goal, which I would also need since Java interop is essential
> to me.
> >>> It fixes a bunch of flaws in the Java type system and adds new
> features like
> >>> nullable types, which I now find it difficult to live without.
> >>>
> >>> Before anyone asks, spec is not useful for me because it relies heavily
> >>> on generative testing to increase your confidence in your functions. I
> can't
> >>> use generative testing because my application is tied to a large Java
> >>> codebase which I cannot model to any useful degree. Essentially, spec
> >>> recommends runtime tests at the boundary of your system, and nearly my
> >>> entire system is interop boundary. I'm not interested in runtime checks
> >>> except where absolutely necessary - Kotlin does this for me
> transparently,
> >>> spec doesn't.
> >>>
> >>> Here's a short list of my findings. I'm happy to expand on any of these
> >>> points if anyone is curious. It bears repeating - Java interop is
> >>> non-negotiable for me, and that makes a lot of this harder than it
> would be
> >>> otherwise.
> >>>
> >>> Disclaimer: I'm no programming language expert. This was hard for me,
> and
> >>> a surprising amount of it was new to me. I'd appreciate any
> corrections or
> >>> clarifications.
> >>>
> >>> Type systems are hard. I for one didn't appreciate the complexity that
> >>> goes into making them easy to use. Don't be fooled by the 20-line
> >>> implementations of Hindley-Milner.
> >>> In particular, generics are very hard, and variance for generic objects
> >>> (i.e. the intersection of generic objects and OO) is the source of much
> >>> difficulty.
> >>> Type systems are split into two main camps - nominal typing (like Java,
> >>> where the types are identified by names) and structural typing, where
> the
> >>> type of an object is defined by it's "shape", like Go's interfaces.
> >>> One of the major benefits of Clojure is its heterogeneous collections,
> >>> a.k.a. "just use a map". This is very difficult to maintain in a
> type-safe
> >>> manner without losing most of the benefit.
> >>> There are two main things I was interested in from a type system - type
> >>> checking (i.e. making sure that your program's types are correct) and
> type
> >>> inference (working out what 

Re: Java like static typing for Clojure?

2016-10-21 Thread Colin Yates
"making me sad" is unsustainable - problem solving with 1s and 0s is
hard enough as it is without using demotivating tools :-).

On 21 October 2016 at 18:40, Colin Fleming  wrote:
> I tried it a couple of years ago, and my impressions were more or less the
> same as CircleCI's here. I found the type annotation burden much higher than
> using a typed language such as Kotlin, the type checking was very slow and
> the boundary between typed and untyped code was really onerous. Ambrose has
> done some great work recently though, so I should check it out again.
> However my general feeling is that retrofitting something like Typed Clojure
> onto an existing language is always going to be more difficult and fraught
> with problems than having a language which was designed with the types in
> mind in the first place.
>
> Another possibility which I haven't had time to explore properly is Allen
> Rohner's spectrum.
>
> Honestly, the easiest solution to my problem is probably just to use Kotlin,
> which was designed by JetBrains for almost exactly my use case, has great
> IDE support, and has a lot of smart people working full-time on it. However
> that has a couple of problems: 1) it would make me sad and 2) I would no
> longer be dogfooding Cursive all the time, which is a valuable source of
> finding bugs during development. But at least I'd be spending all my time on
> developing Cursive features, and not chasing NPEs or investigating all this.
>
> On 21 October 2016 at 19:20, Josh Tilles  wrote:
>>
>> Out of curiosity, did you try Typed Clojure? It certainly has its rough
>> edges, but you sound willing to bear the burden of annotating code with
>> types (at the top-level, at least) and I think its treatment of Java interop
>> does what you want: unless instructed otherwise, the typechecker assumes
>> that arguments to Java methods must not be nil and that any Java method may
>> return nil.
>>
>> On Thursday, October 20, 2016 at 8:39:04 AM UTC-4, Colin Fleming wrote:
>>>
>>> I recently spent a bunch of time researching exactly this. My motivation
>>> was that my main project, Cursive, suffers from a ton of NPEs which I find
>>> very difficult to manage. I wanted to see how difficult it would be to have
>>> a typed Clojure-like thing, using something similar to Kotlin's type system.
>>> Kotlin uses a type system which is similar to Java and has Java interop as a
>>> primary goal, which I would also need since Java interop is essential to me.
>>> It fixes a bunch of flaws in the Java type system and adds new features like
>>> nullable types, which I now find it difficult to live without.
>>>
>>> Before anyone asks, spec is not useful for me because it relies heavily
>>> on generative testing to increase your confidence in your functions. I can't
>>> use generative testing because my application is tied to a large Java
>>> codebase which I cannot model to any useful degree. Essentially, spec
>>> recommends runtime tests at the boundary of your system, and nearly my
>>> entire system is interop boundary. I'm not interested in runtime checks
>>> except where absolutely necessary - Kotlin does this for me transparently,
>>> spec doesn't.
>>>
>>> Here's a short list of my findings. I'm happy to expand on any of these
>>> points if anyone is curious. It bears repeating - Java interop is
>>> non-negotiable for me, and that makes a lot of this harder than it would be
>>> otherwise.
>>>
>>> Disclaimer: I'm no programming language expert. This was hard for me, and
>>> a surprising amount of it was new to me. I'd appreciate any corrections or
>>> clarifications.
>>>
>>> Type systems are hard. I for one didn't appreciate the complexity that
>>> goes into making them easy to use. Don't be fooled by the 20-line
>>> implementations of Hindley-Milner.
>>> In particular, generics are very hard, and variance for generic objects
>>> (i.e. the intersection of generic objects and OO) is the source of much
>>> difficulty.
>>> Type systems are split into two main camps - nominal typing (like Java,
>>> where the types are identified by names) and structural typing, where the
>>> type of an object is defined by it's "shape", like Go's interfaces.
>>> One of the major benefits of Clojure is its heterogeneous collections,
>>> a.k.a. "just use a map". This is very difficult to maintain in a type-safe
>>> manner without losing most of the benefit.
>>> There are two main things I was interested in from a type system - type
>>> checking (i.e. making sure that your program's types are correct) and type
>>> inference (working out what the types of things are from the code, so you
>>> don't have to annotate everything). Type checking is relatively
>>> straightforward, but type inference can be very hard indeed.
>>> Much of the complication comes from the need to interop with Java.
>>> ML-style interface essentially doesn't work if you want to maintain
>>> compatibility with Java since it 

Re: Java like static typing for Clojure?

2016-10-21 Thread Colin Fleming
I tried it a couple of years ago, and my impressions were more or less the
same as CircleCI's here
. I found
the type annotation burden much higher than using a typed language such as
Kotlin, the type checking was very slow and the boundary between typed and
untyped code was really onerous. Ambrose has done some great work recently
though, so I should check it out again. However my general feeling is that
retrofitting something like Typed Clojure onto an existing language is
always going to be more difficult and fraught with problems than having a
language which was designed with the types in mind in the first place.

Another possibility which I haven't had time to explore properly is Allen
Rohner's spectrum .

Honestly, the easiest solution to my problem is probably just to use
Kotlin, which was designed by JetBrains for almost exactly my use case, has
great IDE support, and has a lot of smart people working full-time on it.
However that has a couple of problems: 1) it would make me sad and 2) I
would no longer be dogfooding Cursive all the time, which is a valuable
source of finding bugs during development. But at least I'd be spending all
my time on developing Cursive features, and not chasing NPEs or
investigating all this.

On 21 October 2016 at 19:20, Josh Tilles  wrote:

> Out of curiosity, did you try Typed Clojure? It certainly has its rough
> edges, but you sound willing to bear the burden of annotating code with
> types (at the top-level, at least) and I *think* its treatment of Java
> interop does what you want: unless instructed otherwise, the typechecker
> assumes that arguments to Java methods must not be nil and that any Java
> method may return nil.
>
> On Thursday, October 20, 2016 at 8:39:04 AM UTC-4, Colin Fleming wrote:
>>
>> I recently spent a bunch of time researching exactly this. My motivation
>> was that my main project, Cursive, suffers from a ton of NPEs which I find
>> very difficult to manage. I wanted to see how difficult it would be to have
>> a typed Clojure-like thing, using something similar to Kotlin's type
>> system. Kotlin uses a type system which is similar to Java and has Java
>> interop as a primary goal, which I would also need since Java interop is
>> essential to me. It fixes a bunch of flaws in the Java type system and adds
>> new features like nullable types, which I now find it difficult to live
>> without.
>>
>> Before anyone asks, spec is not useful for me because it relies heavily
>> on generative testing to increase your confidence in your functions. I
>> can't use generative testing because my application is tied to a large Java
>> codebase which I cannot model to any useful degree. Essentially, spec
>> recommends runtime tests at the boundary of your system, and nearly my
>> entire system is interop boundary. I'm not interested in runtime checks
>> except where absolutely necessary - Kotlin does this for me transparently,
>> spec doesn't.
>>
>> Here's a short list of my findings. I'm happy to expand on any of these
>> points if anyone is curious. It bears repeating - Java interop is
>> non-negotiable for me, and that makes a lot of this harder than it would be
>> otherwise.
>>
>> Disclaimer: I'm no programming language expert. This was hard for me, and
>> a surprising amount of it was new to me. I'd appreciate any corrections or
>> clarifications.
>>
>>1. Type systems are hard. I for one didn't appreciate the complexity
>>that goes into making them easy to use. Don't be fooled by the 20-line
>>implementations of Hindley-Milner.
>>2. In particular, generics are very hard, and variance for generic
>>objects (i.e. the intersection of generic objects and OO) is the source of
>>much difficulty.
>>3. Type systems are split into two main camps - nominal typing (like
>>Java, where the types are identified by names) and structural typing, 
>> where
>>the type of an object is defined by it's "shape", like Go's interfaces.
>>4. One of the major benefits of Clojure is its heterogeneous
>>collections, a.k.a. "just use a map". This is very difficult to maintain 
>> in
>>a type-safe manner without losing most of the benefit.
>>5. There are two main things I was interested in from a type system -
>>type checking (i.e. making sure that your program's types are correct) and
>>type inference (working out what the types of things are from the code, so
>>you don't have to annotate everything). Type checking is relatively
>>straightforward, but type inference can be very hard indeed.
>>6. Much of the complication comes from the need to interop with Java.
>>ML-style interface essentially doesn't work if you want to maintain
>>compatibility with Java since it cannot be interfaced in a useful way with
>>nominal OO systems. In particular, method overriding is basically

Re: Java like static typing for Clojure?

2016-10-21 Thread Josh Tilles
Out of curiosity, did you try Typed Clojure? It certainly has its rough 
edges, but you sound willing to bear the burden of annotating code with 
types (at the top-level, at least) and I *think* its treatment of Java 
interop does what you want: unless instructed otherwise, the typechecker 
assumes that arguments to Java methods must not be nil and that any Java 
method may return nil.

On Thursday, October 20, 2016 at 8:39:04 AM UTC-4, Colin Fleming wrote:
>
> I recently spent a bunch of time researching exactly this. My motivation 
> was that my main project, Cursive, suffers from a ton of NPEs which I find 
> very difficult to manage. I wanted to see how difficult it would be to have 
> a typed Clojure-like thing, using something similar to Kotlin's type 
> system. Kotlin uses a type system which is similar to Java and has Java 
> interop as a primary goal, which I would also need since Java interop is 
> essential to me. It fixes a bunch of flaws in the Java type system and adds 
> new features like nullable types, which I now find it difficult to live 
> without.
>
> Before anyone asks, spec is not useful for me because it relies heavily on 
> generative testing to increase your confidence in your functions. I can't 
> use generative testing because my application is tied to a large Java 
> codebase which I cannot model to any useful degree. Essentially, spec 
> recommends runtime tests at the boundary of your system, and nearly my 
> entire system is interop boundary. I'm not interested in runtime checks 
> except where absolutely necessary - Kotlin does this for me transparently, 
> spec doesn't. 
>
> Here's a short list of my findings. I'm happy to expand on any of these 
> points if anyone is curious. It bears repeating - Java interop is 
> non-negotiable for me, and that makes a lot of this harder than it would be 
> otherwise.
>
> Disclaimer: I'm no programming language expert. This was hard for me, and 
> a surprising amount of it was new to me. I'd appreciate any corrections or 
> clarifications.
>
>1. Type systems are hard. I for one didn't appreciate the complexity 
>that goes into making them easy to use. Don't be fooled by the 20-line 
>implementations of Hindley-Milner.
>2. In particular, generics are very hard, and variance for generic 
>objects (i.e. the intersection of generic objects and OO) is the source of 
>much difficulty.
>3. Type systems are split into two main camps - nominal typing (like 
>Java, where the types are identified by names) and structural typing, 
> where 
>the type of an object is defined by it's "shape", like Go's interfaces.
>4. One of the major benefits of Clojure is its heterogeneous 
>collections, a.k.a. "just use a map". This is very difficult to maintain 
> in 
>a type-safe manner without losing most of the benefit.
>5. There are two main things I was interested in from a type system - 
>type checking (i.e. making sure that your program's types are correct) and 
>type inference (working out what the types of things are from the code, so 
>you don't have to annotate everything). Type checking is relatively 
>straightforward, but type inference can be very hard indeed.
>6. Much of the complication comes from the need to interop with Java. 
>ML-style interface essentially doesn't work if you want to maintain 
>compatibility with Java since it cannot be interfaced in a useful way with 
>nominal OO systems. In particular, method overriding is basically 
>impossible to represent.
>7. #6 implies that you cannot have a language with good Java interop 
>*and* global type inference, i.e. you will definitely be annotating 
>your function parameter types, and your function return types. I'm ok with 
>this since IMO it's a good practice anyway.
>8. Once you start thinking about the fact that you no longer have 
>heterogeneous collections, and start thinking about what the alternatives 
>would look like, you start to realise that you'd end up with basically the 
>ML family style of data types - homogeneous collections, typed tuples and 
>ADTs. I'm actually ok with that too, since they're a very nice set of 
>primitives and I think they probably represent 95% of how people use 
>Clojure's collections anyway.
>9. Structural typing seems like it might be a good fit for something 
>like Clojure's maps. However, mixing structural and nominal typing 
>*and* OO seems to be the path to madness.
>
> I think that's it. This is still a project I'd like to tinker with at some 
> point, but I think it's fair to say that I dramatically underestimated the 
> amount of work a useful Java-compatible type system would be. I still think 
> it seems like a nice point in the language design space though, which is 
> curiously unfilled on the JVM (some of you may have noticed that I 
> basically want F# with nullable types).
>
> Cheers,
> Colin
>
> 

Re: Java like static typing for Clojure?

2016-10-21 Thread Colin Fleming
Sure, I'm not arguing that all large projects suffer from this, and I'm not
entirely sure why Cursive does so badly. But the argument I often see
online is the opposite - that Clojure codebases never suffer from this, and
if they do then it must be because of interop, or the application must be
strange in some way. I think this sort of argument is equally disingenuous,
and like I say, I've heard numerous anecdotes to the contrary.

One theory about why Cursive is particularly prone to this that I forgot to
mention - Cursive *is* unusual in that it is run on users' desktops. When
writing, for example, a web application, assuming you're validating your
input you have a reasonable handle on the expected space of inputs, and you
can test various combinations of your application state. For Cursive, that
is much harder - I currently support 6 versions of the underlying IntelliJ
platform, and they run on 3 operating systems. There are two
main IntelliJ configurations (Ultimate and Community). These variations are
actually surprisingly stable and don't tend to create a lot of problems,
but users can also have any combination of plugins installed, and they can
sometimes interact in surprising ways - I've had bugs logged against
Cursive that have turned out to be bugs in the Scala plugin, and vice
versa. Plugins can hook into all sorts of different IDE functionality at
different levels and this can interact in strange ways. I've had a lot of
bugs of this sort, and it's plausible that many of the bugs that are
currently unresolved are a result of this in some way.

In this sort of situation, a static type system which provides universal
guarantees (this value can never be null) is more useful than a contract
system (no null values have been seen yet for the test inputs you've
tried). There's simply no way I can test all combinations, or reproduce all
combinations that users might have running. While the spec'ed core
definitely sounds like something I should try, it will still only work for
the combinations that I actually test unless I leave it running in
production builds.

On 21 October 2016 at 17:51, Alex Miller  wrote:

> Just as a counter-anecdote, I have worked on large Clojure codebases (both
> ones I developed and ones I was unfamiliar with), including ones that
> interfaced with existing Java codebases, and have not experienced this
> problem to the degree you describe Colin. So while I believe these problems
> exist, I don't think it's a foregone conclusion that they must.
>
> FYI, I've found that when working with a partially instrumented spec'ed
> clojure.core, that unexpected nil colls (and colls containing nil) are
> reported earlier and better (because they occur at the point they are
> introduced rather than later and several layers down in some RT method).
>
> On Friday, October 21, 2016 at 10:15:23 AM UTC-5, Colin Fleming wrote:
>>
>> This is a discussion that I've had a couple of times. I don't think that
>> interop is the main factor here, I think it's more that I'm programming
>> against a large codebase I don't understand well (I can't since it's around
>> 4 million LOC). I suspect that if I were programming against a large
>> undocumented Clojure codebase I'd have similar problems, or worse.
>>
>> Note that Java interop often gets the blame here, but it's worth pointing
>> out that in Clojure everything is Java interop in the end. (+ 1 x) or
>> (str/trim x) will give you an NPE as easily as in Java if you pass nil in
>> x. And even if Java interop *is* the root cause of the problem,
>> supposedly interop is idiomatic in Clojure, and interfacing with existing
>> Java systems is a key use case for continuing Clojure adoption. I don't
>> think that the type of application that Cursive is is as much of an outlier
>> as people think - anyone integrating with an existing system will probably
>> face similar problems. Indeed, after my previous conversations, several
>> people contacted me to say that their experience matched mine in similar
>> systems.
>>
>> People have also asked me about whether nil punning helps. In my
>> experience, it allows for some elegant code but it has a really terrible
>> tendency to mask bugs and push them much further into the system than would
>> otherwise be the case. It would be nice to be able to say that I'm
>> expecting a collection to be non-nil, and to get an NPE at the point of the
>> collection call if it's nil due to a bug, rather than just silently
>> returning nil and continuing.
>>
>> Also, when tracking down an NPE from a bug report, if there are
>> collection methods in the stack trace I now have to consider (at least) 3
>> cases: the collection is unexpectedly nil, the collection is unexpectedly
>> empty, or the collection unexpectedly contains a nil value. This greatly
>> increases the space of problems that I have to consider as possibilities
>> when trying to work out what's going on.
>>
>>
>>
>> On 21 October 2016 at 05:39, 

Re: Java like static typing for Clojure?

2016-10-21 Thread Alex Miller
Just as a counter-anecdote, I have worked on large Clojure codebases (both 
ones I developed and ones I was unfamiliar with), including ones that 
interfaced with existing Java codebases, and have not experienced this 
problem to the degree you describe Colin. So while I believe these problems 
exist, I don't think it's a foregone conclusion that they must.

FYI, I've found that when working with a partially instrumented spec'ed 
clojure.core, that unexpected nil colls (and colls containing nil) are 
reported earlier and better (because they occur at the point they are 
introduced rather than later and several layers down in some RT method).

On Friday, October 21, 2016 at 10:15:23 AM UTC-5, Colin Fleming wrote:
>
> This is a discussion that I've had a couple of times. I don't think that 
> interop is the main factor here, I think it's more that I'm programming 
> against a large codebase I don't understand well (I can't since it's around 
> 4 million LOC). I suspect that if I were programming against a large 
> undocumented Clojure codebase I'd have similar problems, or worse. 
>
> Note that Java interop often gets the blame here, but it's worth pointing 
> out that in Clojure everything is Java interop in the end. (+ 1 x) or 
> (str/trim x) will give you an NPE as easily as in Java if you pass nil in 
> x. And even if Java interop *is* the root cause of the problem, 
> supposedly interop is idiomatic in Clojure, and interfacing with existing 
> Java systems is a key use case for continuing Clojure adoption. I don't 
> think that the type of application that Cursive is is as much of an outlier 
> as people think - anyone integrating with an existing system will probably 
> face similar problems. Indeed, after my previous conversations, several 
> people contacted me to say that their experience matched mine in similar 
> systems.
>
> People have also asked me about whether nil punning helps. In my 
> experience, it allows for some elegant code but it has a really terrible 
> tendency to mask bugs and push them much further into the system than would 
> otherwise be the case. It would be nice to be able to say that I'm 
> expecting a collection to be non-nil, and to get an NPE at the point of the 
> collection call if it's nil due to a bug, rather than just silently 
> returning nil and continuing. 
>
> Also, when tracking down an NPE from a bug report, if there are collection 
> methods in the stack trace I now have to consider (at least) 3 cases: the 
> collection is unexpectedly nil, the collection is unexpectedly empty, or 
> the collection unexpectedly contains a nil value. This greatly increases 
> the space of problems that I have to consider as possibilities when trying 
> to work out what's going on.
>
>
>
> On 21 October 2016 at 05:39, Daniel  wrote:
>
>> Just curious... What do you think the primary contributing factor is for 
>> Cursive's NPEs? Java interop?
>>
>> --
>> 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: Java like static typing for Clojure?

2016-10-21 Thread Colin Fleming
This is a discussion that I've had a couple of times. I don't think that
interop is the main factor here, I think it's more that I'm programming
against a large codebase I don't understand well (I can't since it's around
4 million LOC). I suspect that if I were programming against a large
undocumented Clojure codebase I'd have similar problems, or worse.

Note that Java interop often gets the blame here, but it's worth pointing
out that in Clojure everything is Java interop in the end. (+ 1 x) or
(str/trim x) will give you an NPE as easily as in Java if you pass nil in
x. And even if Java interop *is* the root cause of the problem, supposedly
interop is idiomatic in Clojure, and interfacing with existing Java systems
is a key use case for continuing Clojure adoption. I don't think that the
type of application that Cursive is is as much of an outlier as people
think - anyone integrating with an existing system will probably face
similar problems. Indeed, after my previous conversations, several people
contacted me to say that their experience matched mine in similar systems.

People have also asked me about whether nil punning helps. In my
experience, it allows for some elegant code but it has a really terrible
tendency to mask bugs and push them much further into the system than would
otherwise be the case. It would be nice to be able to say that I'm
expecting a collection to be non-nil, and to get an NPE at the point of the
collection call if it's nil due to a bug, rather than just silently
returning nil and continuing.

Also, when tracking down an NPE from a bug report, if there are collection
methods in the stack trace I now have to consider (at least) 3 cases: the
collection is unexpectedly nil, the collection is unexpectedly empty, or
the collection unexpectedly contains a nil value. This greatly increases
the space of problems that I have to consider as possibilities when trying
to work out what's going on.



On 21 October 2016 at 05:39, Daniel  wrote:

> Just curious... What do you think the primary contributing factor is for
> Cursive's NPEs? Java interop?
>
> --
> 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: Slides for my talk at EuroClojure 2016

2016-10-21 Thread Colin Yates
thanks Mauricio

On 21 October 2016 at 14:09, Mauricio Aldazosa
 wrote:
>
>
> On Fri, Oct 21, 2016 at 3:36 AM, Colin Yates  wrote:
>>
>> +1.
>>
>> Remind my old befuddled brain of the JS library used to produce those
>> 3d-like presentations?
>
>
> Looks like reveal.js
>
> Cheers,
> Mauricio
>
> --
> 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: Slides for my talk at EuroClojure 2016

2016-10-21 Thread Mauricio Aldazosa
On Fri, Oct 21, 2016 at 3:36 AM, Colin Yates  wrote:

> +1.
>
> Remind my old befuddled brain of the JS library used to produce those
> 3d-like presentations?
>

Looks like reveal.js 

Cheers,
Mauricio

-- 
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: Slides for my talk at EuroClojure 2016

2016-10-21 Thread Colin Yates
+1.

Remind my old befuddled brain of the JS library used to produce those
3d-like presentations?

On 21 October 2016 at 00:22, Sean Corfield  wrote:
> That is some seriously impressive performance (in the slides) – very nice!
>
>
>
> 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
>
>
>
> On 10/20/16, 4:02 PM, "Dragan Djuric"  draga...@gmail.com> wrote:
>
>
>
> Fixed it to be a hardcoded absolute address. Should work everywhere now.
> Thanks for reporting.
>
>
>
> --
> 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.