Fork me on GitHub
#off-topic
<
2017-08-02
>
qqq00:08:43

hmm, updating to: [org.clojure/clojure "1.9.0-alpha17"] [org.clojure/clojurescript "1.9.854"] appears to have shaved off 10 seconds from 50 to 40 for compile time

qqq00:08:56

(I was on alpha14 + 1.9.4xx)

mobileink00:08:52

wow. wonder why

qqq00:08:50

I read some msgs on google groups, where updaing cljs version improved compile time.

qqq00:08:05

Then I updated cljs version. Then compile time improved.

tbaldridge00:08:13

There's been a lot of compiler improvements in the past few versions of CLJs.

tbaldridge00:08:25

But yeah, if we're talking about fast compile times, someone has to mention Go 😉

tbaldridge00:08:24

But that's the problem, sometimes the compilers are hampered by the language they are compiling. Go is designed from the start to be compiled quickly, and so some features that would be nice (generics, templates, macro systems, etc. ) aren't going to be included anytime soon as they would complicate the compiler.

tbaldridge00:08:56

Likewise, Scala has compile times so slow they would make you cry, but that's the price you pay for about 2-3 type systems in a single compiler.

noisesmith01:08:08

the worst I've ever seen is the stalin scheme compiler

noisesmith01:08:31

OCaml is pretty amazing though - in terms of (language features) / (compile time) as a ratio

darnok17:08:44

Hi. I’know that is a bit off-topic, but do you know any NBA (Next Best Action) systems to use?

qqq18:08:36

Why Clojure is not licensed under GPL, MIT, etc?

MIT and BSD are not reciprocal licenses. I want a reciprocal license. But I don't want the license to apply to, or dictate anything about, non-derivative work that is combined with mine, as GPL does. I think doing so is fundamentally wrong.
What does 'reciprocal' mean here ?

tbaldridge19:08:12

@qqq you can use Clojure more-or-less how ever you want. And by contributing to Clojure you give Rich (and everyone else) the right to use the code however they want

tbaldridge19:08:44

GPL says "you can have this code, but you can't use it to build commercial software"

tbaldridge19:08:58

(gross simplification, and I'm not a lawyer 😉 )

qqq19:08:37

I'm not a fan of GPL. What was the argument vs BSD/MIT ?

noisesmith19:08:41

reciprocal means "if you distribute modifications (or for some extreme licenses, just modify) this code, it needs to be available under the same terms under which you received it"

tbaldridge19:08:45

patents mostly

Drew Verlee19:08:04

When programming in Ruby, do you (anyone willing to answer) find it necessary to have your object instances contain data? I just put my heart and soul into trying to not doing that and i feel like i’m crippling myself. I think the logical argument here is that the only way to get polymorphism in Ruby is through objects. So unless i want to write switch statments, i’m going to need objects w/ data.

donaldball19:08:54

When I was writing both at the same time, and the ruby code was not in the context of rails, I tended to write apis that accepted and returned data to ease coupling, but never tried to keep my internal objects free of data.

donaldball19:08:17

What I did do very often was write immutable objects

schmee19:08:42

I work exclusively in Ruby in my day job, and I try to use hashes instead of objects as much as possible.

schmee19:08:19

I would use a hash instead of a Person object if the object was just used to contain a bunch of fields, since you get the full power of enumerable, all hash methods just work etc.

schmee19:08:12

but if you are dealing with a bunch of state, and some methods operating on the state, I would put it in a class, or the language will work against you

schmee19:08:40

we use immutable objects + dependency injection + factories to help keep things straight

donaldball19:08:45

Surprisingly, the clojure feature I found myself missing more than any other when writing ruby code was protocols

schmee19:08:20

agreed. we sometimes use classes that have a bunch of

def foo
  raise "must implement foo!"
end
to emulate protocols / interfaces, but I’m not sure it’s worth the effort

tbaldridge19:08:09

In the US (and some other countries) you can patent some tech, and release some software as BSD that includes those patents

qqq19:08:13

@noisesmith : I can see how that rules out MIT/BSD

tbaldridge19:08:28

With EPL you also give rights to use your patents as part of the code.

qqq19:08:08

@tbaldridge : I understand the patent/license issue now. This is quite nice.

qqq19:08:49

It's pretty weird to give someone the code, then sue them for patent violation over the code you gave them.

tbaldridge19:08:17

A silly side effect (and I blame the GPL) is that you can't use GPL and EPL code on the same project.

tbaldridge19:08:49

Yeah, I'm not aware of anyone doing that, but the EPL makes corporate lawyers a lot happier.

tbaldridge19:08:10

I worked for a megacorporation once and their policy was "You can never use GPL code on a project, ask permission before using LGPL"

qqq19:08:10

I was okay with GPL until v3 or so -- the "if you run our code on a webserver, and people can access your webserver, you have to make the server side modifications public -- wtf"

qqq19:08:55

[since this is public -- I'm not a lawyer, and none of this is legal advice]

tbaldridge19:08:39

I think the GPL can work for bits of code that should be free forever, like a OS. But even that gets murky when you include modules. Which is why NVidia's GPU drivers are wonky. They don't include them as a kernel module, and they don't compile them. They compile a GPL shim, then map in a binary blob of proprietary data that just happens to be executable.

tbaldridge19:08:38

Nothing is "linked" so the GPL does not apply.

tbaldridge19:08:17

And they have to do that because about 50% of GPU tech is software optimizations, and they don't want that getting out to their competitors.

tbaldridge19:08:30

but that whole situation is just insane, imo.

qqq19:08:01

I'm just glad there are services like rpm fusion, so I can just "dnf install ... nvidia ... "

qqq19:08:12

I remember having to compile nvidia drivers from 'source' before -- was not fun

qqq19:08:35

#### [Why no pattern matching?]()

If you are talking about the aspect of pattern matching that acts as a 
conditional based upon structure, I'm not a big fan. I feel about them 
the way I do about switch statements - they're brittle and 
inextensible. I find the extensive use of them in some functional 
languages an indication of the lack of polymorphism in those 
languages. Some simple uses are fine - i.e. empty list vs not, but 
Clojure's if handles that directly. More complex pattern matches end 
up being switches on type, with the following negatives: 
Is this an argument against core.match and saying the clojure way is to use multimethods instead ?

bronsa20:08:33

multimethods and core.match are not equivalent in power or features

qqq20:08:13

@bronsa : I'm not aruging they are. However, https://gist.github.com/reborg/dc8b0c96c397a56668905e2767fd697f seems to be an argument stating "don't use haskell stype pattern amtching, use multimethods" -- am I reading that wrong?

bronsa20:08:17

I can't speak for rich

roberto20:08:38

I disagree with Rich there. When using a language like Haskell/Scala or Idris, pattern matching is a useful tool that can aid in creating some nice APIs. If Rich is referring solely to Clojure, yeah, pattern matching in Clojure doesn’t give you much.

dpsutton20:08:59

their argument against that is that you can't extend it. and if you don't own the code you can't

dpsutton20:08:23

for instance, in loom, there's an Edge protocol. Anything you make implement Edge can be thrown into the loom mechanism

tbaldridge20:08:24

@qqq it's actually one of the reasons David gave in a talk long ago why progress hasn't continued lately on core.match

tbaldridge20:08:03

I can't find the video now, but the comment was that for pattern matching to fit in well with Clojure's ideals it would need (defmethod ...) like support where any module could come along and extend a matcher

mpenet20:08:27

One doesn't exclude the other imho

dpsutton20:08:33

^ that's the argument for multimethods and protocols. anybody can add into your case statement rather than just the case statement author

dominicm20:08:48

I thought I'd seen a library which does that

tbaldridge20:08:53

for example, stinks to be whomever needs to extend this code: https://github.com/hoon0612/Lisp-in-OCaml/blob/master/types.ml#L15-L22

tbaldridge20:08:59

@dominicm yeah it wouldn't be hard to code up in CLJ with core.match + eval. It'd be really hard to pull off in CLJS

hmaurer20:08:27

@tbaldridge to be honest I didn’t quite understand why it was particularly valuable to extend the internals of a library until I stumbled upon a couple of clojure librairies that weren’t doing exactly what I wanted to, browsed the source code, realised the stuff was implemented as multimethods, extended it myself and it just worked

bronsa20:08:44

sometimes you do want closed dispatch and ordering guarantees tho

bronsa20:08:05

pattern matching is not just about dispatch

tbaldridge20:08:40

Right it's a (ahem) complecting (ahem) of destructuring with dispatch.

dominicm20:08:50

I misunderstood the library a little. No core.match in there.

selfsame20:08:59

same algorithm though 🙂

bronsa20:08:36

so, I have a library I've been working on for the past few weeks where pattern matching is exactly what I needed, no amount of unification/destructuring/dynamic dispatch would do

bronsa20:08:08

I'm not saying I don't prefer protocols/multimethods over pattern matching for implementing custom behaviour, but sometimes you only care and need pattern matching and that is fine

tbaldridge20:08:17

The second argument made by Rich there applies to languages like ML. Where your structs are a lot like tagged tuples, and at runtime the members don't have a name, and cannot be introspected. In that hashmaps are just a lot more flexible

tbaldridge20:08:17

Try writing something like select-keys in OCaml that works against any type, and you'll have real fun time getting that to work.

bronsa20:08:26

playing devil's advocate here for a second, the downside is that you don't get stuff like exhaustiveness checks, so it's tradeoffs

tbaldridge20:08:17

I personally prefer ordered matching, perhaps with optimizations where the compiler can figure out that order doesn't matter.

roberto20:08:33

I find myself using pattern matching for the cases where I do need exhaustive check, and find that a pain to write in Clojure compared to a lang with that feature.

dpsutton20:08:40

for sure about the exhaustiveness

roberto20:08:41

it is about trade offs

dpsutton20:08:49

and it's really nice to see the whole case in one place

roberto20:08:59

and like anything, if misuse pattern matching, you will have a mess too

dpsutton20:08:04

and the dispatch could be different based on which namespaces are on the classpath

mpenet20:08:21

OCaml has polymorphic variants that give a bit of flexibility to do select-keys like func that can work against types that conform to it

mpenet20:08:21

But yeah, it s a very different style of programming, and some concepts from one lang do not necessarily mix well with another

bronsa20:08:37

I still don't see how pattern matching over structured data to pull out bits of it can be done elegantly with destructuring/multimethods

dpsutton20:08:06

yeah i agree about the destructuring stuff

mpenet20:08:17

That d be quite odd and not performant surely

bronsa20:08:46

in my specific case, I'm using core.match to match over symbolic representation of code (more on this if my conj talk is accepted :)), so I want to couple destructuring and dispatch, and I think it's a legitimate use case

mpenet20:08:53

Compared to optimised hand rolled code that a pattern match lib could extend to

tbaldridge20:08:46

sure, but if multimethods supported patters, that'd work as well, right?

bronsa20:08:58

I guess spec conformers somewhat fill that gap, but performance is nowhere near that

mpenet20:08:20

Personally I wished we had pattern matching in core

bronsa20:08:29

nah I wouldn't go that far

tbaldridge20:08:33

I'm really glad we don't.

bronsa20:08:39

a library is fine for the few times you need it

tbaldridge20:08:46

It would encourage a style of programming that really has no place s the norm in Clojure, imo.

bronsa20:08:53

makes you think really hard about whether you want to use that style or not :)

mpenet20:08:19

Just got spoiled by its benefits in other langs i guess

tbaldridge20:08:35

Funny enough, the only time I've wanted pattern matching was when I was writing compilers.

bronsa20:08:48

heh, yeah, close to my use-case

dpsutton20:08:52

that async code is no joke

tbaldridge20:08:54

And when I'm in that mode, the only thing I can think of is "why can't I write this in OCaml"

hmaurer20:08:11

I am writing an interpreter/analysis engine for first-order logic and I have been tempted to use core.match

mpenet20:08:30

Funny, Ocaml is very popular to write compilers & co

bronsa20:08:39

@tbaldridge not sure how you'd make multimethods support patterns? control is off the multimethod dispatcher when you get to a defmulti dispatch value

bronsa20:08:53

unless the defmulti dispatch-fn reacted to a new defmethod being registered

tbaldridge20:08:46

yeah, it would have to be a custom implementation of MultiFn

qqq20:08:46

I've never used open dispatch, but now I'm starting to see it's power.

bronsa20:08:16

open dispatch is not perfect either, you enter in the realm of global mutability

tbaldridge20:08:29

but you could use core.match to do the destructuring/dispatch, then call into the correct method from there. Every time you extend the "defmulti" you'd dump the cached dispatch function and recompile it.

mpenet20:08:34

yup multimethods are super useful

tbaldridge20:08:40

Or actually only compile it on-demand, whould make startup cheaper

bronsa20:08:53

yeah that would work

bronsa20:08:31

but then you're still coupling ordering with dispatch

bronsa20:08:52

you can't tell core.match to ignore an early match and continue matching

bronsa20:08:04

but I guess that's just an implementation detail of this thought experiment

tbaldridge20:08:26

agreed, and that's another type of dispatcher I've wanted in the past. "If there are overlapping rules, execute them both"

dpsutton20:08:44

... in non-deterministic order

tbaldridge20:08:50

yep 🙂

bronsa20:08:52

scarily close to how CLOS works

dpsutton20:08:54

i think that was dykstras's original thought?

dpsutton20:08:09

they all thought parallelism was gonna be rampant by the 80s i think

bronsa20:08:28

and then in the 90s, and then in the 00s...

noisesmith20:08:50

if they had done their job and found the easy way to write correct parallel code, then it would have been

noisesmith20:08:59

so in the big picture it's all their fault that they were wrong

tbaldridge20:08:18

hey! don't actors solve all those problems 😄

bronsa20:08:28

and then in the 90s, and then in the 00s...

qqq21:08:08

clearly the solution is to use racket then in diferent modules, you can do #lang erlang, #lang haskell, #lang clojure and write each module in the way you want

dpsutton21:08:47

that's basically taken over the world, yes

bronsa21:08:28

or use perl 6 and just extend it to support clojure

qqq21:08:02

how hard would it be to port racket's #lang (just the framework, not all the languges) over to clojure?

qqq21:08:16

I'd love to be able to experiment with other languages with the power of clojure as the underlying language

bronsa21:08:17

just as hard as it would be pointless

qqq21:08:38

I'm writing some numericla algorithms in clojure

qqq21:08:46

I'd love to have a #lang numerical ... and then use apl/numpy notation

noisesmith21:08:03

and error on boxing!

noisesmith21:08:39

the syntax is the easy part, there's macros that can do that, keeping numbers unboxed and ops efficient is tricky

qqq21:08:56

there's underlying libraries, like nd4j , jcuda, ...