This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-30
Channels
- # aws (4)
- # beginners (143)
- # boot (37)
- # cider (31)
- # cljs-dev (53)
- # clojure (303)
- # clojure-conj (5)
- # clojure-dev (106)
- # clojure-dusseldorf (2)
- # clojure-greece (3)
- # clojure-italy (23)
- # clojure-spec (83)
- # clojure-uk (7)
- # clojurescript (328)
- # core-async (25)
- # cursive (2)
- # datascript (2)
- # datomic (3)
- # emacs (10)
- # hoplon (1)
- # jobs (2)
- # lein-figwheel (1)
- # leiningen (13)
- # luminus (6)
- # off-topic (38)
- # onyx (2)
- # parinfer (13)
- # pedestal (2)
- # portkey (5)
- # re-frame (11)
- # reagent (2)
- # shadow-cljs (61)
- # specter (6)
- # unrepl (60)
- # vim (4)
Is there a reason apply
can’t apply 0-arity functions? e.g. I’d expect (apply println)
to work.
Which would be useful sometimes e.g. (map apply [println ,,,])
and many other cases.
(map apply [println])
seems more expressive (and general) than (map #(%) [println])
I’m surprised that I can’t seem to find a JIRA for this
Yeah I will… just checking there isn’t one already
just renamed ticket “apply should support application without having to supply args”
as previous name “apply should support 0-arity functions” was technically wrong… as (apply println [])
works
doesn't seem so useful at first but there's a surpising number of cases where it would be
yeah that's what I end up doing, but it's not polyadic and I'd rather a named function
hmm that seems familiar, but I’m struggling to see the utility… can you explain more?
I’m sure I’ve run into the need for it in the past, but can’t for the life of me remember when or why
(defn invoke [f x] (f x))
(defn classify [x]
(condp invoke x
pos? :pos
neg? :neg
zero? :zero))
yeah I think the later is closer to the cases I’ve seen this
but the condp
example would be cute if invoke
existed
though it’s perhaps not sufficiently common to merit being in core
while we're on a ticketing spree, has there been any discussion around allowing underscore in numerical literals in clorjure, ie (def a 1_000_000)
?
I remember somebody asking about it around 2010 in irc, when I first joined the community
@schmee: not sure I like the idea of underscored numerics, as it would presumably have implications for EDN etc too
hard to object to that unless you're more explicit about what those implications are 😉
well I think if the above was supported there might be an expectation on users that EDN should probably support it too, but EDN has many implementations in many languages so adding it to EDN would be a breaking change. Admittedly there’s plenty of clojure syntax not supported in EDN, but this would increase the syntax gap further.
plus perhaps the mixing of _
and -
’s in clojure syntax is perhaps aesthetically displeasing
and you already have the 1e6
syntax
I see your point about EDN but like you say there is already lots of Clojure syntax, and I don't think it should be a requirement to extend EDN to extend Clojure
agreed, but how much syntax for numbers do we need?
it's not a crucial thing for sure, my motivation is that in Java I can write long l = 1_234_567;
, and since Clojure uses long literals, it would be nice if it worked there as well 🙂
I don’t think that is a requirement… but the differences are a barrier for developers… e.g. it’s another thing where copy/pasting between the two will fail
yeah it’s cute and handy for eyeballing long numbers Just pointing out some arguments for why it’s not necessarily good to do. I’m not sure the benefits are worth the cost.
but I’m not clojure core so it’s not me you need to convince 🙂
While we’re on the subject of missing functions @bronsa it’s also frustrating that we have vec
vector
and set
hash-set
constructors, but for hashmaps you only get one hash-map
and have to (apply hash-map ,,,,)
, not sure what you’d call it though, as obviously map
is taken.
yeah was going to say at least we have into
i've sometimes wished vec
set
and the non existent map*
would've been called ->vec
->set
->map
yeah that would’ve been better
There’s no reason we haven’t added the underscore number literal syntax - generally for the primitives we match Java so that would be in line. I think if you are only accepting it as a reader syntax and never printing it, it’s a smaller difference than edn, which could either get it later or not at all
Just a regex change in LispReader
Well, mostly
@rickmoynihan @bronsa I'm pretty sure invoke
is exactly what @rickmoynihan was asking for originally; seems to fit better that having a variant of apply
oh I see alex already commented on the ticket
yeah the reasoning makes sense. invoke is a better name for what I want
@rickmoynihan maybe leave a comment on the invoke ticket with your use case then
have just done that 🙂
My use case is basically I have functions that have had their arguments partially applied and they just need to be called. e.g. things like (map (comp :result invoke) fns)
or variants of
I had a use-case for invoke
. (extend clojure.lang.Keyword Getter {:get invoke})
. But that's the first time in 2 years I think :thinking_face:
(def fizzbuzzes
(let [num str
fizz (constantly "fizz")
buzz (constantly "buzz")
fizzbuzz (constantly "fizzbuzz")
fns [num num fizz
num buzz fizz
num num fizz
buzz num fizz
num num fizzbuzz]]
(map apply (cycle fns)
(map (comp vector inc) (range)))))
I have a feeling that using invoke
instead of apply
, I could have gotten rid of the (comp vector inc)
and only used inc
.
I'm poking around with TryExpr in the compiler (patches incoming! 🙂 ) and I'm trying to understand this part: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2277-L2278
I see that it wraps the try in a fn, but what I don't see is why this is necessary and what it accomplishes
the bytecode for try/catch/finally on the jvm looks very different from that, and requires you to preserve stack height invariants (if I recall)
and doing all that bookkeeping inside nested contexts in a single method is a pain, when you hoist the try out as fn like that, it is compiled in its own method, reducing it to an easier problem
a lot of more complex expressions in the compiled get similar treatment when not in the return context
ahh! so what is different about the return context that makes it not require this special treatment?
the return context is sort of like being a tail call, you don't need to keep track of things to clean up afterwards, you can just return the result
I have an unsuccessful patch that I haven't worked on in a year or two which replaces hoisting as once fns with hoisting to static methods
if you are interested in clojure compilers, the core.async go macro is basically a compiler where the src and target language are both clojure (or clojurescript) an it is written in clojure instead of java
C.RETURN/EXPR vs C.STATEMENT is essentially about stack handling -- to figure out when a value needs to be discarded or a nil needs to pushed onto the stack
and the reason you have to do the stack bookkeeping is because the bytecode verifier will complain otherwise?
you don't want to have different stack depths in different branches, that will mess up things horibly (and the verifier will also complain in some cases)
but also you don't want a function returning void to be in return position and not push nil onto the stack
is the distinction between the statements and expressions a compiler thing or is it visible in the language?