This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-02
Channels
- # announcements (21)
- # babashka (1)
- # beginners (67)
- # calva (18)
- # cider (21)
- # clj-kondo (109)
- # cljs-dev (3)
- # clojure (129)
- # clojure-spec (15)
- # clojure-uk (30)
- # clojurescript (3)
- # datomic (2)
- # graalvm (8)
- # graphql (1)
- # juxt (1)
- # malli (28)
- # off-topic (46)
- # reitit (5)
- # rewrite-clj (33)
- # ring-swagger (2)
- # shadow-cljs (199)
- # vim (9)
I would love to see triple quoted string literals, or anything that's multiline and removes the leading spaces.
@hlolli Just be aware that """foo"""
is already legal Clojure. It's just three consecutive strings:
user=> """foo"""
""
"foo"
""
user=>
If you read the design archive page above, one of the big concerns about this is that it ripples across all the Clojure tools in the ecosystem that parse code (as @vdmit11 found our with REPL-y / nREPL).
And I am fairly certain that the Clojure/core team have rejected this repeatedly...?
So it has to be something beyond triple quotes, something that is not legal syntax today, that cannot break any existing Clojure programs and will be easy for tooling to catch up with (or can already be handled by existing tooling).
@lilactown That won't address the primary issue which is the ability to embed quotes etc without needing escapes.
You can already spread a string across multiple lines.
user=> "
Foo
Bar
"
"\nFoo\nBar\n"
user=>
This is a much harder problem than most people seem to think..
clojure 2.0, just a breaking change language, where all the "nice to have" stuff that was put aside have a chance to be tested out.
I don't have so many examples of nice stuff missing in clojure 🙂 but strings is for sure on my top nice to have list
To be honest, this is not realistic. Python 3 was released more than 10 years ago, but a lot of projects still didn't switch. And all IDEs, syntax highlighters and all sorts of tools will break, and their maintainers will have to support both versions of the language for a long time. I don't think that Clojure community is powerful enough to afford that.
I went to PyCon in 2013. They talked about the 2.7 / 3.0 split and said it would be another five years before they expected 3.0 to be the standard. Six years on, it's not even close. Python 3.x truly split the Python ecosystem and it's still split. This is why Clojure's approach is better.
I've been doing Clojure in production for about eight and a half years. We've been able to run Alpha/Beta builds in production throughout that time because the Clojure/core team take backward compatibility very seriously. That has incredible value, compared to a lot of other languages.
Find a guaranteed, non-breaking way to add a feature you want, sure, I'll be interested. If it breaks my 90,000 lines of code, nope, dead set against.
There are dire warnings from Python's pip that bug fix support will end for Python 2 in 2020, starting early 2019. There are also a bunch of major library maintainers who will stop support Python 2 soon, the list I found is here: https://python3statement.org. That said, I won't be surprised if someone picks up supporting some of those things for at least a while longer for Python 2.
Nothing will change until Python 3.x is the default install on every platform that currently ships with Python 2.7 tho'.
I've been a Fellow of the Python Software Foundation for a decade and man, even if it's the default now, a lot of capital was burned with a lot of core Python people
I was very excited after PyCon 2013 -- Python 3 is a lovely language and the talks about it got me very buzzed! I went back to work, determined to replace all of our random bash scripts with nice, maintainable .py
files... and then found that everything was still 2.7 and it was kind of a PITA to not only get Python3 installed but to navigate the world of packages to find what actually ran on Python 3 😞
Speaking of which, if you really want to do triple quoted strings and use python strings interpolation, you can always use libpython-clj
😈
Really @U3BALC2HH? Could you share a working example showing that?
I'm still waiting @U3BALC2HH -- where's that example?
Lol it's 11:29 on a Friday night Sean
but here, just for you:
(require '[libpython-clj.python :as py])
(py/initialize!)
(-> (py/run-simple-string "x=\\
'''tripple
quoted
string
'''
")
:globals
(get "x"))
;; => "tripple\nquoted\nstring\n"
Wow, that's a pretty miserable way to write a docstring :rolling_on_the_floor_laughing:
And it's using '''
inside "
so it's a complete "cheat" as far as the original discussion was concerned.
(and don't complain about the time if you're trying to "pick a fight" over language or semantics 🙂 )
Hey man, there’s a talk on it at clojure/conj, I thought it was neat? ¯\(ツ)/¯
Sure, it's neat that you can "dip into Python" inside a function call from Clojure -- and it was Clojure/South I think, not Clojure/conj? -- but that's a far cry from what was being discused.
Which arcs back to the "discussion" you tried to have yesterday.
You are being controversial/argumentative for no useful reason. It's really not appreciated.
Dial it back if you want to continue to be a member of this community, OK/
(this reflects pretty much every interaction I've seen with you here)
10am, Friday
So, not a talk that you have seen.
Not a talk you've seen that you "thought was neat".
Random walk through libpython-clj
. I'm excited about it. Sorry it's coming across the wrong way to you. I'm really not trying to start anything. Would be happy to discuss it at the conj if you're there :)
I don't know why you like to provoke weird arguments over stuff -- the whole lazy/eager/unevaluated stuff the other day was just really unpleasant.
I will be at Conj. Happy to discuss over a beer. I'll buy. But you are pretty disruptive here, even if you don't mean to be.
Sorry, I get a little overly passionate about language semantics. Would you say I'm a little overly "eager" myself? ;). Perhaps even greedily... 😂
I know "text" doesn't always convey emotion. Something to consider, given how badly everyone reacted to that...
Yeah, maybe. Just... I dunno... try to dial it back a bit?
Looking forward to beers 🍻
Perhaps keep that stuff in #off-topic ?
No offense meant
I'm always looking forward to beers. I arrive Wednesday morning (because of a red-eye).
We'll be there Monday :)
We? Ah, multiple J.J.'s? 🙂
East Coast? (I'm West Coast)
Rust has a technique I had not seen before for this. You can use as many # marks before a " as you want, and the terminating " must have that many # after it, or it is not the string end.
I'm using test.chuck
to parse regexes and I want to write a generative test that requires generating regexes; is there a way for a lazy person to use instaparse to turn parse trees back into strings?
You mean like this? https://github.com/aengelberg/instagenerate 🙂
test.chuck
has a regex generator -- isn't that suffiicent?
test.chuck has a thing that takes a regex and produces strings matching it, I'm looking to generate new regexes
(context: I'm writing https://github.com/lvh/regex-crossword and trying to come up with cool pathological examples)
Oh... gotcha... wow... regexes all the way down.
(I'm writing a blog post to go with it to demo core.logic and Clojure in general so I care extra about quality and exposition)
Does Rust dislike being hosted? Eh, it's not the default, but it's not like they hate WASM
Also mostly the people I've met in the Rust community are nice and the same is true for Clojure
(Perhaps you do not believe being a jerk can be an ideological language position but that has not been my experience)
Anyway I hope we can all be friends -- sincerely, the person who spends way too much time figuring out how to call C ABI libraries properly from Clojure
I like Rust and the community is great. I think as a language approach, yes, it is very different to Clojure but I don't think it's fair to call it "ideologically opposite to Clojure".
It definitely shares goal. Create a modern language free of data races, designed for the multi-core, multi-processor era, with concurrency and parallelism in mind
It kinda embraces an industry standard by being built on top of LLVM same way Clojure is built on JVM
Bindings are immutable by default. And it guides you towards safe idioms, but still gives you escape hatch when you need more raw performance.
And its pretty functional and not so much OO, in that it favours interfaces the same way Clojure does, and open implementation of them over classes and inheritance.
The biggest difference is that it's not a Lisp, and it heavily relies on static compile time types to achieve those goals, while Clojure relies more on dynamic runtime constructs to do so.
Because of its linear types, it can afford to provide more mutability, but I think the guarantees of the borrow checker make it so it is still following the spirit of Clojure. Clojure makes similar choices in a few places, when mutability doesn't leak or exposes people to data races, Clojure allows it.
Good summary @didibus
somewhat related, i remember a quote somewhere that went something like "functional programming is a clever demonstration that you can write code without mutation that woks, rust is an even more clever demonstration that you can do the same with mutation"
Given a seq of ints [2r11 2r1101]
, I want to add them such that (add-them [2r11 2r1101]) -> 2r0000001100001101
which is 781 in base10.
Basically I want to add 0's to LSB of each int to make in an octet, and then string them up.
I can do this through string manipulation, but I suppose there should be a more elegant approach using bitwise operators, any suggestions ?
@murtaza52 haven't thought a whole lot about your specific case, but there's bit-and and bit-or: https://clojuredocs.org/clojure.core/bit-and https://clojuredocs.org/clojure.core/bit-or
@dpsutton thanks that worked like a charm (bit-or (bit-shift-left 0x03 8) 0x0D)
I was always thinking in terms of the second operand, but the trick was bit shifting the first one.
I'm trying to reduce in reverse so to iterate from the last index and on through until the 0 index? Can you please help me: https://stackoverflow.com/questions/58673766/how-to-reduce-in-reverse-so-to-iterate-from-the-last-index-and-on-through-until?noredirect=1#comment103649307_58673766
I know evaluation order of set literals is undefined. But what is the reasoning behind this?
(def a (atom 0))
(defn inca [] (swap! a inc))
#{(inca) (inca)} ;; Duplicate key: (inca)
Thanks. Do you know why that is?
same thing with map literals. {:a 3}
uses literals. {(foo) 1 (foo) 2}
aren't literals
another way to put it: the constraint is not a runtime constraint, it is a reader constraint, the reader doesn't care what (foo)
means and treats two instances of (foo)
as two of the same value
Thanks, I’m working on a self-interpreter but found this hard to replicate. But now that I see it’s the reader not the evaluator that reports this it makes sense again.
the executor has another layer of check {(+ 1 1) :x (- 3 1) :y}
also errors, but at a different stage
Yes I know.
cool - wanted to make sure my answer here was complete (Execution error vs. Syntax error)
That was very nice of you, thank you.
There is rseq
that is like seq
, only works for 'reversible' collections, and returns a seq in the reverse order that seq
does. Vectors are reversible collections, as are sorted sets and maps. Not sure if anything else is.
anyone know anything about the origins of the wording of the new tap>
functions? Is "tap" synonymous with "send this value to a queue without blocking and handlers can be added to process the queue"? Is there a more precise definition?
The same verb is used in core.async for mults, which multiply data flowing over a channel, you put data in to the source channel, and the mult copies the data to each channel that has tapped (been tapped? tapped into?) the mult
Oh yeah, I hadn't considered that about core.async/tap
. I'm reconsidering the naming of some functions I use. Essentially side-effecting functions can be added to a set of functions (in an atom) which are all run in turn on each new incoming value of a stream. Essentially the same as the tap>
feature. Currently using the terms handlers
/`add-handler` but i'm not sure if that has a connotation that the return value should be meaningful when it's not for these functions, and the word tap
is starting to grow on me for some reason
In my experience handler
is a common term for the kind of function you describe, and does not imply that the return value is meaningful. FWIW.
Another common term is subscriber
.
i think in brewing whiskey and wine you tap a large vat to sample without disturbing the main process. to me tap
sounds like siphon a bit for sampling
Also in plumbing, a tap can be created in an existing water pipe, even when water is still flowing through it: https://www.youtube.com/watch?v=NMADW0epBiY
tap meaning a branch off of the main water flow
Also there's the phrase "to tap into"
tap or tap into [TRANSITIVE] if you tap something such as someone’s ability or a supply of information, you use it or get some benefit from it : Are you tapping your staff’s full potential?
Several other companies were already tapping this market.
(found this here:
https://ell.stackexchange.com/questions/58077/why-does-tap-into-mean-what-it-means)I am pretty sure that tap in wire tap was inspired by the earlier meanings
fwiw, there's this: https://www.etymonline.com/word/tap