Clojurians
#cljs-dev
<
2018-01-31
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

richiardiandrea02:01:25

Hi @mfikes & @darwin I had a question..what is the scope of the cljs-oss organization on GitHub? There is one tiny tiny cljs project that deserves some love and I was wondering whether it would be a good idea to "share" it under an :umbrella: org :smile:

richiardiandrea02:01:08

Sorry for the ping :sweat_smile:

mfikes02:01:38

@richiardiandrea Here is the discussion that led to the creation of that organization: https://clojurians-log.clojureverse.org/cljs-dev/2017-07-05.html

richiardiandrea02:01:20

Ok cool so my small adopted lib would not be a good fit there :smile_cat:

andy.fingerhut06:01:59

mfikes posted a message in the last week or so on a single 'clj' command line to start a cljs repl. Does anyone have that handy? I thought I could find it by searching on Slack, but either it has fallen out of the history, or I am just not choosing the right search terms. Anyone have that handy?

anmonteiro06:01:12

@andy.fingerhut I believe it might be this tweet: https://twitter.com/mfikes/status/955957557184614401

andy.fingerhut07:01:31

@anmonteiro That was it. Thanks.

mfikes14:01:06

If empty were defined as

(defn empty [coll] 
  (when (implements? IEmptyableCollection coll) 
    (-empty coll)))
it would seem to more closely match the semantics of Clojure's empty (with a simple example being the case of passing a non-collection: (empty "abc")). Is my thinking flawed here? (Apart from perf implications.)

rauh14:01:34

@mfikes There are def a few people out there extending native types for -empty and this would break it.

mfikes14:01:55

@rauh OK, so satisfies? would be needed

rauh14:01:51

@mfikes Yeah, or how we often do it: First check for implements, then dispatch with ^not-native hint and then check for statisfies and dispatch to protocol dispatcher.

rauh14:01:18

I guess we currently throw whereas Clojure silently return nil. So yeah, we do have a semnatic mismatch here.

rauh14:01:46

Another option is to just do a extend-type default which we also do for hash & iequiv

mfikes14:01:36

I could see an argument that empty only takes collections, but, with no spec for empty, it is tempting to derive the semantics from the Clojure implementation.

mfikes14:01:45

I'll write up a JIRA so the presumed semantic mismatch is captured.

alexmiller15:01:41

regarding empty and things that don’t work with it ….

alexmiller15:01:36

the reason why records and map entries don’t work with empty is because they are fixed size tuples and it does not make sense to have a fixed size tuple that has 0 entries/elements

alexmiller15:01:09

semantics that align with that idea are good ones

alexmiller15:01:46

we don’t have explicit tuple types in Clojure, which is what makes this harder to talk about. Rich went down that road back in the 1.7-ish timeframe but ultimately found that it did not perform well enough to replace small vector usage (mostly due to megamorphic de-optimizations)

alexmiller15:01:29

while having empty return nil as the fallback is the current documented behavior, I would find it difficult to defend that design decision. It’s hard for me to come up with a scenario where that seems like the right answer. :)

alexmiller15:01:40

records throw UnsupportedOperationException if you try to empty them and that seems better

rauh15:01:27

I agree, I think the current impl which throws is better than silently returning nil, even if it's different to CLJ.

mfikes15:01:19

I wonder, does (empty "abc") only work accidentally in Clojure? In other words, is it an invalid program with undefined semantics?

dnolen15:01:19

probably one for @alexmiller

alexmiller15:01:43

as always, I would suggest reading the docstring

alexmiller15:01:25

in this case, it says “, or nil” which implies to me that it is intentionally returning nil for non-collection use cases. That does not make sense to me personally.

alexmiller15:01:49

while there many punny cases where nil is handy, it is not clear to me that this is one of them :)

alexmiller15:01:29

(empty nil) ;; => nil is probably useful

mfikes16:01:25

FWIW, my intent with the above was to simply make ClojureScript match Clojure's semantics. (While also only guessing at what those semantics truly are, and cheating by looking at the implementation.)

alexmiller16:01:13

I hear ya. I don’t think it would be a bad thing if cljs deviated in disallowing empty on things that are not collections or nil

mfikes16:01:50

And, I failed in my analysis, missing the behavior for records :slightly_smiling_face:

alexmiller16:01:14

so records are tricky in that they are collections and will probably pass any type check but throw in the impl

alexmiller16:01:23

in Clojure at least

mfikes16:01:13

(Part of me feels like simply waiting on these kinds of things where there is a bit of uncertainty for the point when specs are written, which nails things down, in a sense.)

alexmiller16:01:46

the problem is that there are 100s of methods that require this kind of interpretation :)

mfikes16:01:58

If you had to spec empty that would be an interesting task... hrm

alexmiller16:01:48

Clojure actually has a test-empty test that checks things like (and (= (empty "abc") nil))

alexmiller16:01:12

but I think that’s more tests written from looking at the impl, than tests that should predict the behavior

alexmiller16:01:07

(ignore the and there, that’s some test detritus)

alexmiller16:01:24

I think I would spec it as (s/fdef clojure.core/empty :args (s/cat :c (s/nilable coll?)) :ret (s/nilable coll?))

mfikes16:01:48

I forget, is there a desire / goal to ultimately spec the core functions, where feasible?

alexmiller16:01:10

yes, and I’ve worked on it at times

alexmiller16:01:28

one of the issues is whether you proactively load them

alexmiller16:01:45

loading 100s of specs on startup is unlikely to make anyone happy wrt startup time

alexmiller16:01:17

so I think you would want them in a separate namespace (from the existing macro specs) so you can choose whether and when to load them

mfikes16:01:40

For now, I've "self-declined" https://dev.clojure.org/jira/browse/CLJS-2489 as being premature, especially if the spec for empty ends up invalidating the questionable reversed engineered semantics in that ticket.